From 1325ba6dffdeefdfd2a6bfd7b1f5d05bc28b65ee Mon Sep 17 00:00:00 2001 From: "John M. Schanck" Date: Wed, 9 Sep 2020 16:10:44 -0400 Subject: [PATCH] Remove old HQC implementations --- crypto_kem/hqc-128-1-cca2/META.yml | 23 - crypto_kem/hqc-128-1-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-128-1-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-128-1-cca2/leaktime/api.h | 25 - crypto_kem/hqc-128-1-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-128-1-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-128-1-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-128-1-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-128-1-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-128-1-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-128-1-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-128-1-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-128-1-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-128-1-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-128-1-cca2/leaktime/kem.c | 154 ----- .../hqc-128-1-cca2/leaktime/parameters.h | 112 ---- crypto_kem/hqc-128-1-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-128-1-cca2/leaktime/parsing.h | 20 - .../hqc-128-1-cca2/leaktime/repetition.c | 100 --- .../hqc-128-1-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-128-1-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-128-1-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-128-1-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-128-1-cca2/leaktime/util.h | 9 - crypto_kem/hqc-128-1-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-128-1-cca2/leaktime/vector.h | 22 - crypto_kem/hqc-192-1-cca2/META.yml | 23 - crypto_kem/hqc-192-1-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-192-1-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-192-1-cca2/leaktime/api.h | 25 - crypto_kem/hqc-192-1-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-192-1-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-192-1-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-192-1-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-192-1-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-192-1-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-192-1-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-192-1-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-192-1-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-192-1-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-192-1-cca2/leaktime/kem.c | 154 ----- .../hqc-192-1-cca2/leaktime/parameters.h | 109 --- crypto_kem/hqc-192-1-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-192-1-cca2/leaktime/parsing.h | 20 - .../hqc-192-1-cca2/leaktime/repetition.c | 100 --- .../hqc-192-1-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-192-1-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-192-1-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-192-1-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-192-1-cca2/leaktime/util.h | 9 - crypto_kem/hqc-192-1-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-192-1-cca2/leaktime/vector.h | 22 - crypto_kem/hqc-192-2-cca2/META.yml | 23 - crypto_kem/hqc-192-2-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-192-2-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-192-2-cca2/leaktime/api.h | 25 - crypto_kem/hqc-192-2-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-192-2-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-192-2-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-192-2-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-192-2-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-192-2-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-192-2-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-192-2-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-192-2-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-192-2-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-192-2-cca2/leaktime/kem.c | 154 ----- .../hqc-192-2-cca2/leaktime/parameters.h | 109 --- crypto_kem/hqc-192-2-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-192-2-cca2/leaktime/parsing.h | 20 - .../hqc-192-2-cca2/leaktime/repetition.c | 100 --- .../hqc-192-2-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-192-2-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-192-2-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-192-2-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-192-2-cca2/leaktime/util.h | 9 - crypto_kem/hqc-192-2-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-192-2-cca2/leaktime/vector.h | 22 - crypto_kem/hqc-256-1-cca2/META.yml | 23 - crypto_kem/hqc-256-1-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-256-1-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-256-1-cca2/leaktime/api.h | 25 - crypto_kem/hqc-256-1-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-256-1-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-256-1-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-256-1-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-256-1-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-256-1-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-256-1-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-256-1-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-256-1-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-256-1-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-256-1-cca2/leaktime/kem.c | 154 ----- .../hqc-256-1-cca2/leaktime/parameters.h | 109 --- crypto_kem/hqc-256-1-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-256-1-cca2/leaktime/parsing.h | 20 - .../hqc-256-1-cca2/leaktime/repetition.c | 100 --- .../hqc-256-1-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-256-1-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-256-1-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-256-1-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-256-1-cca2/leaktime/util.h | 9 - crypto_kem/hqc-256-1-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-256-1-cca2/leaktime/vector.h | 22 - crypto_kem/hqc-256-2-cca2/META.yml | 23 - crypto_kem/hqc-256-2-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-256-2-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-256-2-cca2/leaktime/api.h | 25 - crypto_kem/hqc-256-2-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-256-2-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-256-2-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-256-2-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-256-2-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-256-2-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-256-2-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-256-2-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-256-2-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-256-2-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-256-2-cca2/leaktime/kem.c | 154 ----- .../hqc-256-2-cca2/leaktime/parameters.h | 112 ---- crypto_kem/hqc-256-2-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-256-2-cca2/leaktime/parsing.h | 20 - .../hqc-256-2-cca2/leaktime/repetition.c | 100 --- .../hqc-256-2-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-256-2-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-256-2-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-256-2-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-256-2-cca2/leaktime/util.h | 9 - crypto_kem/hqc-256-2-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-256-2-cca2/leaktime/vector.h | 22 - crypto_kem/hqc-256-3-cca2/META.yml | 23 - crypto_kem/hqc-256-3-cca2/leaktime/LICENSE | 1 - crypto_kem/hqc-256-3-cca2/leaktime/Makefile | 19 - .../leaktime/Makefile.Microsoft_nmake | 23 - crypto_kem/hqc-256-3-cca2/leaktime/api.h | 25 - crypto_kem/hqc-256-3-cca2/leaktime/bch.c | 295 -------- crypto_kem/hqc-256-3-cca2/leaktime/bch.h | 16 - crypto_kem/hqc-256-3-cca2/leaktime/fft.c | 628 ------------------ crypto_kem/hqc-256-3-cca2/leaktime/fft.h | 18 - crypto_kem/hqc-256-3-cca2/leaktime/gf.c | 99 --- crypto_kem/hqc-256-3-cca2/leaktime/gf.h | 18 - crypto_kem/hqc-256-3-cca2/leaktime/gf2x.c | 123 ---- crypto_kem/hqc-256-3-cca2/leaktime/gf2x.h | 13 - crypto_kem/hqc-256-3-cca2/leaktime/hqc.c | 135 ---- crypto_kem/hqc-256-3-cca2/leaktime/hqc.h | 15 - crypto_kem/hqc-256-3-cca2/leaktime/kem.c | 154 ----- .../hqc-256-3-cca2/leaktime/parameters.h | 112 ---- crypto_kem/hqc-256-3-cca2/leaktime/parsing.c | 126 ---- crypto_kem/hqc-256-3-cca2/leaktime/parsing.h | 20 - .../hqc-256-3-cca2/leaktime/repetition.c | 100 --- .../hqc-256-3-cca2/leaktime/repetition.h | 14 - crypto_kem/hqc-256-3-cca2/leaktime/tensor.c | 42 -- crypto_kem/hqc-256-3-cca2/leaktime/tensor.h | 14 - crypto_kem/hqc-256-3-cca2/leaktime/util.c | 69 -- crypto_kem/hqc-256-3-cca2/leaktime/util.h | 9 - crypto_kem/hqc-256-3-cca2/leaktime/vector.c | 224 ------- crypto_kem/hqc-256-3-cca2/leaktime/vector.h | 22 - 162 files changed, 14133 deletions(-) delete mode 100644 crypto_kem/hqc-128-1-cca2/META.yml delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-128-1-cca2/leaktime/vector.h delete mode 100644 crypto_kem/hqc-192-1-cca2/META.yml delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-192-1-cca2/leaktime/vector.h delete mode 100644 crypto_kem/hqc-192-2-cca2/META.yml delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-192-2-cca2/leaktime/vector.h delete mode 100644 crypto_kem/hqc-256-1-cca2/META.yml delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-256-1-cca2/leaktime/vector.h delete mode 100644 crypto_kem/hqc-256-2-cca2/META.yml delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-256-2-cca2/leaktime/vector.h delete mode 100644 crypto_kem/hqc-256-3-cca2/META.yml delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/LICENSE delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/Makefile delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/Makefile.Microsoft_nmake delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/api.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/bch.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/bch.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/fft.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/fft.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/gf.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/gf.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/gf2x.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/gf2x.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/hqc.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/hqc.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/kem.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/parameters.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/parsing.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/parsing.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/repetition.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/repetition.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/tensor.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/tensor.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/util.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/util.h delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/vector.c delete mode 100644 crypto_kem/hqc-256-3-cca2/leaktime/vector.h diff --git a/crypto_kem/hqc-128-1-cca2/META.yml b/crypto_kem/hqc-128-1-cca2/META.yml deleted file mode 100644 index 9ea157c9..00000000 --- a/crypto_kem/hqc-128-1-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_128_1_CCA2 -type: kem -claimed-nist-level: 1 -claimed-security: IND-CCA2 -length-public-key: 3125 -length-ciphertext: 6234 -length-secret-key: 3165 -length-shared-secret: 64 -nistkat-sha256: 29b6545c85a9aaf75572f112b4d4cf9078c716147f84072c4efe4ce5160f18e0 -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/LICENSE b/crypto_kem/hqc-128-1-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/Makefile b/crypto_kem/hqc-128-1-cca2/leaktime/Makefile deleted file mode 100644 index 466c8aaf..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-128-1-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-128-1-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index f8c06ff5..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-128-1-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/api.h b/crypto_kem/hqc-128-1-cca2/leaktime/api.h deleted file mode 100644 index 2972fb6e..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_128_1_CCA2" - -#define PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 3165 -#define PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 3125 -#define PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 6234 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/bch.c b/crypto_kem/hqc-128-1-cca2/leaktime/bch.c deleted file mode 100644 index 3c5b0acc..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC1281CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC1281CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC1281CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/bch.h b/crypto_kem/hqc-128-1-cca2/leaktime/bch.h deleted file mode 100644 index 07f301ec..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/fft.c b/crypto_kem/hqc-128-1-cca2/leaktime/fft.c deleted file mode 100644 index 3d1f5ae3..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1281CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1281CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/fft.h b/crypto_kem/hqc-128-1-cca2/leaktime/fft.h deleted file mode 100644 index 8927b53f..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC1281CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/gf.c b/crypto_kem/hqc-128-1-cca2/leaktime/gf.c deleted file mode 100644 index 8f1fd20d..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/gf.h b/crypto_kem/hqc-128-1-cca2/leaktime/gf.h deleted file mode 100644 index 7c609439..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC1281CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.c b/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.c deleted file mode 100644 index 4f3af030..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC1281CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC1281CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.h b/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.h deleted file mode 100644 index 8d376936..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/hqc.c b/crypto_kem/hqc-128-1-cca2/leaktime/hqc.c deleted file mode 100644 index 6c922279..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/hqc.h b/crypto_kem/hqc-128-1-cca2/leaktime/hqc.h deleted file mode 100644 index 5ac79a4a..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/kem.c b/crypto_kem/hqc-128-1-cca2/leaktime/kem.c deleted file mode 100644 index 143c4497..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC1281CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC1281CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/parameters.h b/crypto_kem/hqc-128-1-cca2/leaktime/parameters.h deleted file mode 100644 index 429e2ffd..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/parameters.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 24677 -#define PARAM_N1 796 -#define PARAM_N2 31 -#define PARAM_N1N2 24676 -#define PARAM_OMEGA 67 -#define PARAM_OMEGA_E 77 -#define PARAM_OMEGA_R 77 -#define PARAM_SECURITY 128 -#define PARAM_DFR_EXP 128 - -#define SECRET_KEY_BYTES PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC1281CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16755683 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 15 - -#define PARAM_DELTA 60 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 541 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0, \ - 1,0,0,1,0,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,0,1,0,1,0,1,1,0,0, \ - 1,0,1,0,0,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,1,0, \ - 0,1,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,1,1,1,1,0,1,0,0,1,1,1,1,0,1, \ - 0,0,0,1,0,0,1,1,1,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,0, \ - 1,1,0,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,1,0,1,0,0,1,0,0,1,1,0,1,0, \ - 0,0,0,1,1,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1, \ - 1,0,1,1,0,0,0,1,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,1,0, \ - 0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,0,1,1, \ - 1,1,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,1,1,1,0,1,0,1, \ - 0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,0,0, \ - 1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1, \ - 0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1,1, \ - 0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,1,0,0,1,0,0,1,1,0,0, \ - 0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,1,0,0,0,0,1,0,1,1, \ - 1,1,0,0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,0, \ - 1,0,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/parsing.c b/crypto_kem/hqc-128-1-cca2/leaktime/parsing.c deleted file mode 100644 index 9e94fa1f..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/parsing.h b/crypto_kem/hqc-128-1-cca2/leaktime/parsing.h deleted file mode 100644 index 130efdc4..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC1281CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/repetition.c b/crypto_kem/hqc-128-1-cca2/leaktime/repetition.c deleted file mode 100644 index 8e83d7fe..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/repetition.h b/crypto_kem/hqc-128-1-cca2/leaktime/repetition.h deleted file mode 100644 index cc53cadd..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/tensor.c b/crypto_kem/hqc-128-1-cca2/leaktime/tensor.c deleted file mode 100644 index 2fc24179..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1281CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC1281CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/tensor.h b/crypto_kem/hqc-128-1-cca2/leaktime/tensor.h deleted file mode 100644 index 9f4e2b6d..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1281CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/util.c b/crypto_kem/hqc-128-1-cca2/leaktime/util.c deleted file mode 100644 index 1253d4c8..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC1281CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC1281CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC1281CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC1281CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC1281CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/util.h b/crypto_kem/hqc-128-1-cca2/leaktime/util.h deleted file mode 100644 index 65fd6491..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC1281CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC1281CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC1281CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/vector.c b/crypto_kem/hqc-128-1-cca2/leaktime/vector.c deleted file mode 100644 index e0c7e7f6..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC1281CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-128-1-cca2/leaktime/vector.h b/crypto_kem/hqc-128-1-cca2/leaktime/vector.h deleted file mode 100644 index 6c8cd3a6..00000000 --- a/crypto_kem/hqc-128-1-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC1281CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC1281CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC1281CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC1281CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/META.yml b/crypto_kem/hqc-192-1-cca2/META.yml deleted file mode 100644 index 3ca1d9bd..00000000 --- a/crypto_kem/hqc-192-1-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_192_1_CCA2 -type: kem -claimed-nist-level: 3 -claimed-security: IND-CCA2 -length-public-key: 5499 -length-ciphertext: 10981 -length-secret-key: 5539 -length-shared-secret: 64 -nistkat-sha256: ddff72bfd7bf33a9fa1b3c70a05378b0544e57207b5bb9205cacd6d69002d597 -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/LICENSE b/crypto_kem/hqc-192-1-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/Makefile b/crypto_kem/hqc-192-1-cca2/leaktime/Makefile deleted file mode 100644 index 3893c887..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-192-1-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-192-1-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index 9c053300..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-192-1-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/api.h b/crypto_kem/hqc-192-1-cca2/leaktime/api.h deleted file mode 100644 index c8916267..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_192_1_CCA2" - -#define PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 5539 -#define PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 5499 -#define PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 10981 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/bch.c b/crypto_kem/hqc-192-1-cca2/leaktime/bch.c deleted file mode 100644 index 891a7fa1..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC1921CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC1921CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC1921CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/bch.h b/crypto_kem/hqc-192-1-cca2/leaktime/bch.h deleted file mode 100644 index 040fb253..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/fft.c b/crypto_kem/hqc-192-1-cca2/leaktime/fft.c deleted file mode 100644 index e14c6179..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1921CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1921CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/fft.h b/crypto_kem/hqc-192-1-cca2/leaktime/fft.h deleted file mode 100644 index e64a5410..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC1921CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/gf.c b/crypto_kem/hqc-192-1-cca2/leaktime/gf.c deleted file mode 100644 index 82bb043e..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/gf.h b/crypto_kem/hqc-192-1-cca2/leaktime/gf.h deleted file mode 100644 index 044a7871..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC1921CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.c b/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.c deleted file mode 100644 index c53efa0f..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC1921CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC1921CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.h b/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.h deleted file mode 100644 index 9b7a0a6f..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/hqc.c b/crypto_kem/hqc-192-1-cca2/leaktime/hqc.c deleted file mode 100644 index a7758de7..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/hqc.h b/crypto_kem/hqc-192-1-cca2/leaktime/hqc.h deleted file mode 100644 index f493bce4..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/kem.c b/crypto_kem/hqc-192-1-cca2/leaktime/kem.c deleted file mode 100644 index 52868ae2..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC1921CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC1921CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/parameters.h b/crypto_kem/hqc-192-1-cca2/leaktime/parameters.h deleted file mode 100644 index 094d8274..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/parameters.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 43669 -#define PARAM_N1 766 -#define PARAM_N2 57 -#define PARAM_N1N2 43662 -#define PARAM_OMEGA 101 -#define PARAM_OMEGA_E 117 -#define PARAM_OMEGA_R 117 -#define PARAM_SECURITY 192 -#define PARAM_DFR_EXP 128 - -#define SECRET_KEY_BYTES PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC1921CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16768896 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 28 - -#define PARAM_DELTA 57 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 511 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,0,0,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,0,0,1,1,0,1,1, \ - 1,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0, \ - 0,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,0,0,1,0,0,1,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, \ - 1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,1,1,1,0,1,0, \ - 0,1,1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,1,0, \ - 1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,1,1,0,1,0,0,0,0,1,0, \ - 0,1,0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,0,0,0,1,0,1, \ - 1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0, \ - 1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1, \ - 1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,0,1,0,0,1,1,1,1,1,0,1,0,1, \ - 0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1, \ - 1,0,1,0,0,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1, \ - 0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,1,1,1,1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1, \ - 1,0,1,1,1,0,0,0,0,1,1,0,1,1,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/parsing.c b/crypto_kem/hqc-192-1-cca2/leaktime/parsing.c deleted file mode 100644 index c7b81b0b..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/parsing.h b/crypto_kem/hqc-192-1-cca2/leaktime/parsing.h deleted file mode 100644 index 23d8908e..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC1921CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/repetition.c b/crypto_kem/hqc-192-1-cca2/leaktime/repetition.c deleted file mode 100644 index 09a0149f..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/repetition.h b/crypto_kem/hqc-192-1-cca2/leaktime/repetition.h deleted file mode 100644 index 66485ab9..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/tensor.c b/crypto_kem/hqc-192-1-cca2/leaktime/tensor.c deleted file mode 100644 index 8ab2ed87..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1921CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC1921CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/tensor.h b/crypto_kem/hqc-192-1-cca2/leaktime/tensor.h deleted file mode 100644 index e4c8e4cc..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1921CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/util.c b/crypto_kem/hqc-192-1-cca2/leaktime/util.c deleted file mode 100644 index 868c0790..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC1921CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC1921CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC1921CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC1921CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC1921CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/util.h b/crypto_kem/hqc-192-1-cca2/leaktime/util.h deleted file mode 100644 index 1928a443..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC1921CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC1921CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC1921CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/vector.c b/crypto_kem/hqc-192-1-cca2/leaktime/vector.c deleted file mode 100644 index 3aa7b520..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC1921CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-192-1-cca2/leaktime/vector.h b/crypto_kem/hqc-192-1-cca2/leaktime/vector.h deleted file mode 100644 index 049adeea..00000000 --- a/crypto_kem/hqc-192-1-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC1921CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC1921CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC1921CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC1921CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/META.yml b/crypto_kem/hqc-192-2-cca2/META.yml deleted file mode 100644 index cd4ce8da..00000000 --- a/crypto_kem/hqc-192-2-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_192_2_CCA2 -type: kem -claimed-nist-level: 3 -claimed-security: IND-CCA2 -length-public-key: 5884 -length-ciphertext: 11749 -length-secret-key: 5924 -length-shared-secret: 64 -nistkat-sha256: 838916e26585828d15cabb7a0a0b9dabb63986e432735b7f6cf2ee0e823bcca3 -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/LICENSE b/crypto_kem/hqc-192-2-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/Makefile b/crypto_kem/hqc-192-2-cca2/leaktime/Makefile deleted file mode 100644 index 26b0cdf9..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-192-2-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-192-2-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index 3f0c1590..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-192-2-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/api.h b/crypto_kem/hqc-192-2-cca2/leaktime/api.h deleted file mode 100644 index 489ea798..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_192_2_CCA2" - -#define PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 5924 -#define PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 5884 -#define PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 11749 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/bch.c b/crypto_kem/hqc-192-2-cca2/leaktime/bch.c deleted file mode 100644 index 3e222c04..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC1922CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC1922CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC1922CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/bch.h b/crypto_kem/hqc-192-2-cca2/leaktime/bch.h deleted file mode 100644 index 8db18705..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/fft.c b/crypto_kem/hqc-192-2-cca2/leaktime/fft.c deleted file mode 100644 index 4cf68aaf..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1922CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC1922CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/fft.h b/crypto_kem/hqc-192-2-cca2/leaktime/fft.h deleted file mode 100644 index 785fe766..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC1922CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/gf.c b/crypto_kem/hqc-192-2-cca2/leaktime/gf.c deleted file mode 100644 index fb70d97d..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/gf.h b/crypto_kem/hqc-192-2-cca2/leaktime/gf.h deleted file mode 100644 index 574340a5..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC1922CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.c b/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.c deleted file mode 100644 index 2505dab3..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC1922CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC1922CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.h b/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.h deleted file mode 100644 index 5e8f14b7..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/hqc.c b/crypto_kem/hqc-192-2-cca2/leaktime/hqc.c deleted file mode 100644 index 9b883442..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/hqc.h b/crypto_kem/hqc-192-2-cca2/leaktime/hqc.h deleted file mode 100644 index 15a7a3ff..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/kem.c b/crypto_kem/hqc-192-2-cca2/leaktime/kem.c deleted file mode 100644 index 1a48651f..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC1922CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC1922CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/parameters.h b/crypto_kem/hqc-192-2-cca2/leaktime/parameters.h deleted file mode 100644 index f095b43d..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/parameters.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 46747 -#define PARAM_N1 766 -#define PARAM_N2 61 -#define PARAM_N1N2 46726 -#define PARAM_OMEGA 101 -#define PARAM_OMEGA_E 117 -#define PARAM_OMEGA_R 117 -#define PARAM_SECURITY 192 -#define PARAM_DFR_EXP 192 - -#define SECRET_KEY_BYTES PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC1922CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16735426 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 30 - -#define PARAM_DELTA 57 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 511 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,0,0,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,0,0,1,1,0,1,1, \ - 1,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0, \ - 0,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,0,0,1,0,0,1,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, \ - 1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,1,1,1,0,1,0, \ - 0,1,1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,1,0, \ - 1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,1,1,0,1,0,0,0,0,1,0, \ - 0,1,0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,0,0,0,1,0,1, \ - 1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0, \ - 1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1, \ - 1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,0,1,0,0,1,1,1,1,1,0,1,0,1, \ - 0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1, \ - 1,0,1,0,0,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1, \ - 0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,1,1,1,1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1, \ - 1,0,1,1,1,0,0,0,0,1,1,0,1,1,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/parsing.c b/crypto_kem/hqc-192-2-cca2/leaktime/parsing.c deleted file mode 100644 index 36bf5678..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/parsing.h b/crypto_kem/hqc-192-2-cca2/leaktime/parsing.h deleted file mode 100644 index ebb725f0..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC1922CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/repetition.c b/crypto_kem/hqc-192-2-cca2/leaktime/repetition.c deleted file mode 100644 index 996b55d8..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/repetition.h b/crypto_kem/hqc-192-2-cca2/leaktime/repetition.h deleted file mode 100644 index da49ca70..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/tensor.c b/crypto_kem/hqc-192-2-cca2/leaktime/tensor.c deleted file mode 100644 index f211033a..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC1922CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC1922CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/tensor.h b/crypto_kem/hqc-192-2-cca2/leaktime/tensor.h deleted file mode 100644 index e7dc6e42..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC1922CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/util.c b/crypto_kem/hqc-192-2-cca2/leaktime/util.c deleted file mode 100644 index 3ee71a44..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC1922CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC1922CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC1922CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC1922CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC1922CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/util.h b/crypto_kem/hqc-192-2-cca2/leaktime/util.h deleted file mode 100644 index ab992499..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC1922CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC1922CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC1922CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/vector.c b/crypto_kem/hqc-192-2-cca2/leaktime/vector.c deleted file mode 100644 index d4454f03..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC1922CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-192-2-cca2/leaktime/vector.h b/crypto_kem/hqc-192-2-cca2/leaktime/vector.h deleted file mode 100644 index 951c54cf..00000000 --- a/crypto_kem/hqc-192-2-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC1922CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC1922CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC1922CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC1922CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/META.yml b/crypto_kem/hqc-256-1-cca2/META.yml deleted file mode 100644 index 85f4afc9..00000000 --- a/crypto_kem/hqc-256-1-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_256_1_CCA2 -type: kem -claimed-nist-level: 5 -claimed-security: IND-CCA2 -length-public-key: 7989 -length-ciphertext: 15961 -length-secret-key: 8029 -length-shared-secret: 64 -nistkat-sha256: 339bd96be8b2d6bfb12315550b16827c612b41ab7aa4585ded55d2bf87410968 -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/LICENSE b/crypto_kem/hqc-256-1-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/Makefile b/crypto_kem/hqc-256-1-cca2/leaktime/Makefile deleted file mode 100644 index 847cfde0..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-256-1-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-256-1-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index 41cb3809..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-256-1-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/api.h b/crypto_kem/hqc-256-1-cca2/leaktime/api.h deleted file mode 100644 index 51fe5cad..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_256_1_CCA2" - -#define PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 8029 -#define PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 7989 -#define PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 15961 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/bch.c b/crypto_kem/hqc-256-1-cca2/leaktime/bch.c deleted file mode 100644 index 2600ec1a..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC2561CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC2561CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC2561CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/bch.h b/crypto_kem/hqc-256-1-cca2/leaktime/bch.h deleted file mode 100644 index ab94cdee..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/fft.c b/crypto_kem/hqc-256-1-cca2/leaktime/fft.c deleted file mode 100644 index e0ebf626..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2561CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2561CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/fft.h b/crypto_kem/hqc-256-1-cca2/leaktime/fft.h deleted file mode 100644 index 2091eda8..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC2561CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/gf.c b/crypto_kem/hqc-256-1-cca2/leaktime/gf.c deleted file mode 100644 index 81da2f02..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/gf.h b/crypto_kem/hqc-256-1-cca2/leaktime/gf.h deleted file mode 100644 index 4dee7806..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC2561CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.c b/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.c deleted file mode 100644 index 519acb23..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC2561CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC2561CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.h b/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.h deleted file mode 100644 index 4da1c16a..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/hqc.c b/crypto_kem/hqc-256-1-cca2/leaktime/hqc.c deleted file mode 100644 index 642a794e..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/hqc.h b/crypto_kem/hqc-256-1-cca2/leaktime/hqc.h deleted file mode 100644 index 72157a68..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/kem.c b/crypto_kem/hqc-256-1-cca2/leaktime/kem.c deleted file mode 100644 index daeb9aa9..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC2561CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC2561CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/parameters.h b/crypto_kem/hqc-256-1-cca2/leaktime/parameters.h deleted file mode 100644 index dd96ea38..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/parameters.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 63587 -#define PARAM_N1 766 -#define PARAM_N2 83 -#define PARAM_N1N2 63578 -#define PARAM_OMEGA 133 -#define PARAM_OMEGA_E 153 -#define PARAM_OMEGA_R 153 -#define PARAM_SECURITY 256 -#define PARAM_DFR_EXP 128 - -#define SECRET_KEY_BYTES PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC2561CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16723381 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 41 - -#define PARAM_DELTA 57 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 511 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,0,0,0,1,0,0,1,1,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1,1,1,1,1,0,0,1,1,0,1,1, \ - 1,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,1,0,1,1,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0, \ - 0,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,0,0,1,0,0,1,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, \ - 1,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,0,1,0,1,0,1,1,1,1,0,1,0, \ - 0,1,1,0,1,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,1,1,1,0, \ - 1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,1,1,0,1,0,0,0,0,1,0, \ - 0,1,0,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,0,0,0,1,0,1, \ - 1,1,1,1,1,0,1,0,1,0,1,1,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,0, \ - 1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1, \ - 1,1,1,0,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,0,1,0,0,1,1,1,1,1,0,1,0,1, \ - 0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1, \ - 1,0,1,0,0,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,0,0,0,1,1, \ - 0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,1,1,1,1,0,0,0,1,0,0,1,1,0,1,1,0,0,1,0,1, \ - 1,0,1,1,1,0,0,0,0,1,1,0,1,1,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/parsing.c b/crypto_kem/hqc-256-1-cca2/leaktime/parsing.c deleted file mode 100644 index 98de6dfd..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/parsing.h b/crypto_kem/hqc-256-1-cca2/leaktime/parsing.h deleted file mode 100644 index 652b51a8..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC2561CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/repetition.c b/crypto_kem/hqc-256-1-cca2/leaktime/repetition.c deleted file mode 100644 index 1119cf03..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/repetition.h b/crypto_kem/hqc-256-1-cca2/leaktime/repetition.h deleted file mode 100644 index 0a32a261..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/tensor.c b/crypto_kem/hqc-256-1-cca2/leaktime/tensor.c deleted file mode 100644 index 52981c33..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2561CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC2561CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/tensor.h b/crypto_kem/hqc-256-1-cca2/leaktime/tensor.h deleted file mode 100644 index ea1cc11e..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2561CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/util.c b/crypto_kem/hqc-256-1-cca2/leaktime/util.c deleted file mode 100644 index fb5a9540..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC2561CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC2561CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC2561CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC2561CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC2561CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/util.h b/crypto_kem/hqc-256-1-cca2/leaktime/util.h deleted file mode 100644 index 93f7b921..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC2561CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC2561CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC2561CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/vector.c b/crypto_kem/hqc-256-1-cca2/leaktime/vector.c deleted file mode 100644 index feab7d84..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC2561CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-256-1-cca2/leaktime/vector.h b/crypto_kem/hqc-256-1-cca2/leaktime/vector.h deleted file mode 100644 index 750c9240..00000000 --- a/crypto_kem/hqc-256-1-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC2561CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC2561CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC2561CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC2561CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/META.yml b/crypto_kem/hqc-256-2-cca2/META.yml deleted file mode 100644 index 09130c43..00000000 --- a/crypto_kem/hqc-256-2-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_256_2_CCA2 -type: kem -claimed-nist-level: 5 -claimed-security: IND-CCA2 -length-public-key: 8503 -length-ciphertext: 16985 -length-secret-key: 8543 -length-shared-secret: 64 -nistkat-sha256: df224b5438e4958b636d0d5353c869c65c9b881cc8e8fc940295013b191e213c -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/LICENSE b/crypto_kem/hqc-256-2-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/Makefile b/crypto_kem/hqc-256-2-cca2/leaktime/Makefile deleted file mode 100644 index 78248987..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-256-2-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-256-2-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index dab014ac..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-256-2-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/api.h b/crypto_kem/hqc-256-2-cca2/leaktime/api.h deleted file mode 100644 index f35b126f..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_256_2_CCA2" - -#define PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 8543 -#define PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 8503 -#define PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 16985 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/bch.c b/crypto_kem/hqc-256-2-cca2/leaktime/bch.c deleted file mode 100644 index 581d407e..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC2562CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC2562CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC2562CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/bch.h b/crypto_kem/hqc-256-2-cca2/leaktime/bch.h deleted file mode 100644 index eef59649..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/fft.c b/crypto_kem/hqc-256-2-cca2/leaktime/fft.c deleted file mode 100644 index 12beff4a..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2562CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2562CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/fft.h b/crypto_kem/hqc-256-2-cca2/leaktime/fft.h deleted file mode 100644 index 3f42ad82..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC2562CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/gf.c b/crypto_kem/hqc-256-2-cca2/leaktime/gf.c deleted file mode 100644 index c8e82c42..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/gf.h b/crypto_kem/hqc-256-2-cca2/leaktime/gf.h deleted file mode 100644 index f81709a4..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC2562CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.c b/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.c deleted file mode 100644 index 4058ed70..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC2562CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC2562CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.h b/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.h deleted file mode 100644 index 9cdb82fc..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/hqc.c b/crypto_kem/hqc-256-2-cca2/leaktime/hqc.c deleted file mode 100644 index 66bd7934..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/hqc.h b/crypto_kem/hqc-256-2-cca2/leaktime/hqc.h deleted file mode 100644 index 44a9713c..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/kem.c b/crypto_kem/hqc-256-2-cca2/leaktime/kem.c deleted file mode 100644 index b83fef61..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC2562CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC2562CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/parameters.h b/crypto_kem/hqc-256-2-cca2/leaktime/parameters.h deleted file mode 100644 index 04dec2f8..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/parameters.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 67699 -#define PARAM_N1 796 -#define PARAM_N2 85 -#define PARAM_N1N2 67660 -#define PARAM_OMEGA 133 -#define PARAM_OMEGA_E 153 -#define PARAM_OMEGA_R 153 -#define PARAM_SECURITY 256 -#define PARAM_DFR_EXP 192 - -#define SECRET_KEY_BYTES PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC2562CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16721653 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 42 - -#define PARAM_DELTA 60 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 541 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0, \ - 1,0,0,1,0,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,0,1,0,1,0,1,1,0,0, \ - 1,0,1,0,0,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,1,0, \ - 0,1,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,1,1,1,1,0,1,0,0,1,1,1,1,0,1, \ - 0,0,0,1,0,0,1,1,1,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,0, \ - 1,1,0,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,1,0,1,0,0,1,0,0,1,1,0,1,0, \ - 0,0,0,1,1,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1, \ - 1,0,1,1,0,0,0,1,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,1,0, \ - 0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,0,1,1, \ - 1,1,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,1,1,1,0,1,0,1, \ - 0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,0,0, \ - 1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1, \ - 0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1,1, \ - 0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,1,0,0,1,0,0,1,1,0,0, \ - 0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,1,0,0,0,0,1,0,1,1, \ - 1,1,0,0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,0, \ - 1,0,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/parsing.c b/crypto_kem/hqc-256-2-cca2/leaktime/parsing.c deleted file mode 100644 index 05a5993d..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/parsing.h b/crypto_kem/hqc-256-2-cca2/leaktime/parsing.h deleted file mode 100644 index 1f9a08d3..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC2562CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/repetition.c b/crypto_kem/hqc-256-2-cca2/leaktime/repetition.c deleted file mode 100644 index 11e10f3e..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/repetition.h b/crypto_kem/hqc-256-2-cca2/leaktime/repetition.h deleted file mode 100644 index 18473a72..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/tensor.c b/crypto_kem/hqc-256-2-cca2/leaktime/tensor.c deleted file mode 100644 index 9b4ef5d2..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2562CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC2562CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/tensor.h b/crypto_kem/hqc-256-2-cca2/leaktime/tensor.h deleted file mode 100644 index 61940065..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2562CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/util.c b/crypto_kem/hqc-256-2-cca2/leaktime/util.c deleted file mode 100644 index c85867bb..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC2562CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC2562CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC2562CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC2562CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC2562CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/util.h b/crypto_kem/hqc-256-2-cca2/leaktime/util.h deleted file mode 100644 index 4851d4a7..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC2562CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC2562CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC2562CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/vector.c b/crypto_kem/hqc-256-2-cca2/leaktime/vector.c deleted file mode 100644 index 1afe22f2..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC2562CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-256-2-cca2/leaktime/vector.h b/crypto_kem/hqc-256-2-cca2/leaktime/vector.h deleted file mode 100644 index aab09565..00000000 --- a/crypto_kem/hqc-256-2-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC2562CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC2562CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC2562CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC2562CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/META.yml b/crypto_kem/hqc-256-3-cca2/META.yml deleted file mode 100644 index dd7c367a..00000000 --- a/crypto_kem/hqc-256-3-cca2/META.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: HQC_256_3_CCA2 -type: kem -claimed-nist-level: 5 -claimed-security: IND-CCA2 -length-public-key: 8897 -length-ciphertext: 17777 -length-secret-key: 8937 -length-shared-secret: 64 -nistkat-sha256: e0bb4e73a1a27f05ddb1138685922bf4a40c2e535b5152b93135c06a73777770 -principal-submitters: - - Carlos Aguilar Melchor - - Nicolas Aragon - - Slim Bettaieb - - Loïc Bidoux - - Olivier Blazy - - Jean-Christophe Deneuville - - Philippe Gaborit - - Edoardo Persichetti - - Gilles Zémor -auxiliary-submitters: [] -implementations: - - name: leaktime - version: https://pqc-hqc.org/doc/hqc-reference-implementation_2019-08-24.zip diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/LICENSE b/crypto_kem/hqc-256-3-cca2/leaktime/LICENSE deleted file mode 100644 index 85265b0a..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/LICENSE +++ /dev/null @@ -1 +0,0 @@ -Public domain diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/Makefile b/crypto_kem/hqc-256-3-cca2/leaktime/Makefile deleted file mode 100644 index 2e9689c6..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# This Makefile can be used with GNU Make or BSD Make - -LIB=libhqc-256-3-cca2_leaktime.a -HEADERS=api.h bch.h fft.h gf.h gf2x.h hqc.h parameters.h parsing.h repetition.h tensor.h vector.h util.h -OBJECTS=bch.o fft.o gf.o gf2x.o hqc.o kem.o parsing.o repetition.o tensor.o vector.o util.o - -CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c -o $@ $< - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/Makefile.Microsoft_nmake b/crypto_kem/hqc-256-3-cca2/leaktime/Makefile.Microsoft_nmake deleted file mode 100644 index 767f0cf4..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/Makefile.Microsoft_nmake +++ /dev/null @@ -1,23 +0,0 @@ -# This Makefile can be used with Microsoft Visual Studio's nmake using the command: -# nmake /f Makefile.Microsoft_nmake - -LIBRARY=libhqc-256-3-cca2_leaktime.lib -OBJECTS=bch.obj fft.obj gf.obj gf2x.obj hqc.obj kem.obj parsing.obj repetition.obj tensor.obj vector.obj util.obj - -# We ignore warning C4127: we sometimes use a conditional that depending -# on the parameters results in a case where if (const) is the case. -# The compiler should just optimise this away, but on MSVC we get -# a compiler complaint. -CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4127 - -all: $(LIBRARY) - -# Make sure objects are recompiled if headers change. -$(OBJECTS): *.h - -$(LIBRARY): $(OBJECTS) - LIB.EXE /NOLOGO /WX /OUT:$@ $** - -clean: - -DEL $(OBJECTS) - -DEL $(LIBRARY) diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/api.h b/crypto_kem/hqc-256-3-cca2/leaktime/api.h deleted file mode 100644 index e11adee3..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/api.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_API_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_API_H - -/** - * \file api.h - * \brief NIST KEM API used by the HQC_KEM IND-CCA2 scheme - */ - -#include - -#define PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_ALGNAME "HQC_256_3_CCA2" - -#define PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES 8937 -#define PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES 8897 -#define PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_BYTES 64 -#define PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES 17777 - -// As a technicality, the public key is appended to the secret key in order to respect the NIST API. -// Without this constraint, CRYPTO_SECRETKEYBYTES would be defined as 32 - -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/bch.c b/crypto_kem/hqc-256-3-cca2/leaktime/bch.c deleted file mode 100644 index d9a819a5..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/bch.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * @file bch.c - * Constant time implementation of BCH codes - */ - -#include "bch.h" -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include "vector.h" -#include -#include - -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message); -static void lfsr_encode(uint8_t *codeword, const uint8_t *message); -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked); -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes); -static void message_from_codeword(uint8_t *message, const uint8_t *codeword); -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector); -static void compute_roots(uint8_t *error, const uint16_t *sigma); - - -/** - * @brief Unpacks the message message to the array message_unpacked where each byte stores a bit of the message - * - * @param[out] message_unpacked Array of VEC_K_SIZE_BYTES bytes receiving the unpacked message - * @param[in] message Array of PARAM_K bytes storing the packed message - */ -static void unpack_message(uint8_t *message_unpacked, const uint8_t *message) { - for (size_t i = 0; i < (VEC_K_SIZE_BYTES - (PARAM_K % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - message_unpacked[j + 8 * i] = (message[i] >> j) & 0x01; - } - } - - for (int8_t j = 0; j < PARAM_K % 8; ++j) { - message_unpacked[j + 8 * (VEC_K_SIZE_BYTES - 1)] = (message[VEC_K_SIZE_BYTES - 1] >> j) & 0x01; - } -} - - - -/** - * @brief Encodes the message message to a codeword codeword using the generator polynomial bch_poly of the code - * - * @param[out] codeword Array of PARAM_N1 bytes receiving the codeword - * @param[in] message Array of PARAM_K bytes storing the message to encode - */ -static void lfsr_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t gate_value = 0; - uint8_t bch_poly[PARAM_G] = PARAM_BCH_POLY; - - // Compute the Parity-check digits - for (int16_t i = PARAM_K - 1; i >= 0; --i) { - gate_value = message[i] ^ codeword[PARAM_N1 - PARAM_K - 1]; - - for (size_t j = PARAM_N1 - PARAM_K - 1; j; --j) { - codeword[j] = codeword[j - 1] ^ (-gate_value & bch_poly[j]); - } - - codeword[0] = gate_value; - } - - // Add the message - memcpy(codeword + PARAM_N1 - PARAM_K, message, PARAM_K); -} - - - -/** - * @brief Packs the codeword from an array codeword_unpacked where each byte stores a bit to a compact array codeword - * - * @param[out] codeword Array of VEC_N1_SIZE_BYTES bytes receiving the packed codeword - * @param[in] codeword_unpacked Array of PARAM_N1 bytes storing the unpacked codeword - */ -static void pack_codeword(uint8_t *codeword, const uint8_t *codeword_unpacked) { - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0)); ++i) { - for (size_t j = 0; j < 8; ++j) { - codeword[i] |= codeword_unpacked[j + 8 * i] << j; - } - } - - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - codeword[VEC_N1_SIZE_BYTES - 1] |= codeword_unpacked[j + 8 * (VEC_N1_SIZE_BYTES - 1)] << j; - } -} - - - -/** - * @brief Encodes a message message of PARAM_K bits to a BCH codeword codeword of PARAM_N1 bits - * - * Following @cite lin1983error (Chapter 4 - Cyclic Codes), - * We perform a systematic encoding using a linear (PARAM_N1 - PARAM_K)-stage shift register - * with feedback connections based on the generator polynomial bch_poly of the BCH code. - * - * @param[out] codeword Array of size VEC_N1_SIZE_BYTES receiving the encoded message - * @param[in] message Array of size VEC_K_SIZE_BYTES storing the message - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message) { - uint8_t message_unpacked[PARAM_K]; - uint8_t codeword_unpacked[PARAM_N1] = {0}; - - unpack_message(message_unpacked, message); - lfsr_encode(codeword_unpacked, message_unpacked); - pack_codeword(codeword, codeword_unpacked); -} - - - -/** - * @brief Computes the error locator polynomial (ELP) sigma - * - * This is a constant time implementation of Berlekamp's simplified algorithm (see @cite joiner1995decoding).
- * We use the letter p for rho which is initialized at -1/2.
- * The array X_sigma_p represents the polynomial X^(2(mu-rho))*sigma_p(X).
- * Instead of maintaining a list of sigmas, we update in place both sigma and X_sigma_p.
- * sigma_copy serves as a temporary save of sigma in case X_sigma_p needs to be updated.
- * We can properly correct only if the degree of sigma does not exceed PARAM_DELTA. - * This means only the first PARAM_DELTA + 1 coefficients of sigma are of value - * and we only need to save its first PARAM_DELTA - 1 coefficients. - * - * @returns the degree of the ELP sigma - * @param[out] sigma Array of size (at least) PARAM_DELTA receiving the ELP - * @param[in] syndromes Array of size (at least) 2*PARAM_DELTA storing the syndromes - */ -static size_t compute_elp(uint16_t *sigma, const uint16_t *syndromes) { - sigma[0] = 1; - size_t deg_sigma = 0; - size_t deg_sigma_p = 0; - uint16_t sigma_copy[PARAM_DELTA - 1] = {0}; - size_t deg_sigma_copy = 0; - uint16_t X_sigma_p[PARAM_DELTA + 1] = {0, 1}; - int32_t pp = -1; // 2*rho - uint16_t d_p = 1; - uint16_t d = syndromes[0]; - - for (size_t mu = 0; mu < PARAM_DELTA; ++mu) { - // Save sigma in case we need it to update X_sigma_p - memcpy(sigma_copy, sigma, 2 * (PARAM_DELTA - 1)); - deg_sigma_copy = deg_sigma; - - uint16_t dd = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(d, PQCLEAN_HQC2563CCA2_LEAKTIME_gf_inverse(d_p)); // 0 if(d == 0) - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - sigma[i] ^= PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(dd, X_sigma_p[i]); - } - - size_t deg_X = 2 * mu - pp; // 2*(mu-rho) - size_t deg_X_sigma_p = deg_X + deg_sigma_p; - - // mask1 = 0xffff if(d != 0) and 0 otherwise - int16_t mask1 = -((uint16_t) - d >> 15); - - // mask2 = 0xffff if(deg_X_sigma_p > deg_sigma) and 0 otherwise - int16_t mask2 = -((uint16_t) (deg_sigma - deg_X_sigma_p) >> 15); - - // mask12 = 0xffff if the deg_sigma increased and 0 otherwise - int16_t mask12 = mask1 & mask2; - deg_sigma = (mask12 & deg_X_sigma_p) ^ (~mask12 & deg_sigma); - - if (mu == PARAM_DELTA - 1) { - break; - } - - // Update pp, d_p and X_sigma_p if needed - pp = (mask12 & (2 * mu)) ^ (~mask12 & pp); - d_p = (mask12 & d) ^ (~mask12 & d_p); - for (size_t i = PARAM_DELTA - 1; i; --i) { - X_sigma_p[i + 1] = (mask12 & sigma_copy[i - 1]) ^ (~mask12 & X_sigma_p[i - 1]); - } - X_sigma_p[1] = 0; - X_sigma_p[0] = 0; - deg_sigma_p = (mask12 & deg_sigma_copy) ^ (~mask12 & deg_sigma_p); - - // Compute the next discrepancy - d = syndromes[2 * mu + 2]; - for (size_t i = 1; (i <= 2 * mu + 1) && (i <= PARAM_DELTA); ++i) { - d ^= PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(sigma[i], syndromes[2 * mu + 2 - i]); - } - } - - return deg_sigma; -} - - - -/** - * @brief Retrieves the message message from the codeword codeword - * - * Since we performed a systematic encoding, the message is the last PARAM_K bits of the codeword. - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the message - * @param[in] codeword Array of size VEC_N1_SIZE_BYTES storing the codeword - */ -static void message_from_codeword(uint8_t *message, const uint8_t *codeword) { - int32_t val = PARAM_N1 - PARAM_K; - - uint8_t mask1 = 0xff << val % 8; - uint8_t mask2 = 0xff >> (8 - val % 8); - size_t index = val / 8; - - for (size_t i = 0; i < VEC_K_SIZE_BYTES - 1; ++i) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[i] = message1 | message2; - } - - // Last byte (8-val % 8 is the number of bits given by message1) - if ((PARAM_K % 8 == 0) || (8 - val % 8 < PARAM_K % 8)) { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - uint8_t message2 = (codeword[++index] & mask2) << (8 - val % 8); - message[VEC_K_SIZE_BYTES - 1] = message1 | message2; - } else { - uint8_t message1 = (codeword[index] & mask1) >> val % 8; - message[VEC_K_SIZE_BYTES - 1] = message1; - } -} - - - -/** - * @brief Computes the 2^PARAM_DELTA syndromes from the received vector vector - * - * Syndromes are the sum of powers of alpha weighted by vector's coefficients. - * To do so, we use the additive FFT transpose, which takes as input a family w of GF(2^PARAM_M) elements - * and outputs the weighted power sums of these w.
- * Therefore, this requires twisting and applying a permutation before feeding vector to the fft transpose.
- * For more details see Berstein, Chou and Schawbe's explanations: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] syndromes Array of size 2^(PARAM_FFT_T) receiving the 2*PARAM_DELTA syndromes - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -static void compute_syndromes(uint16_t *syndromes, const uint8_t *vector) { - uint16_t w[1 << PARAM_M]; - - PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(w, vector); - PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t(syndromes, w, 2 * PARAM_DELTA); -} - - - -/** - * @brief Computes the error polynomial error from the error locator polynomial sigma - * - * See function fft for more details. - * - * @param[out] err Array of VEC_N1_SIZE_BYTES elements receiving the error polynomial - * @param[in] sigma Array of 2^PARAM_FFT elements storing the error locator polynomial - */ -static void compute_roots(uint8_t *error, const uint16_t *sigma) { - uint16_t w[1 << PARAM_M] = {0}; // w will receive the evaluation of sigma in all field elements - - PQCLEAN_HQC2563CCA2_LEAKTIME_fft(w, sigma, PARAM_DELTA + 1); - PQCLEAN_HQC2563CCA2_LEAKTIME_fft_retrieve_bch_error_poly(error, w); -} - - - -/** - * @brief Decodes the received word - * - * This function relies on four steps: - *
    - *
  1. The first step, done by additive FFT transpose, is the computation of the 2*PARAM_DELTA syndromes. - *
  2. The second step is the computation of the error-locator polynomial sigma. - *
  3. The third step, done by additive FFT, is finding the error-locator numbers by calculating the roots of the polynomial sigma and takings their inverses. - *
  4. The fourth step is the correction of the errors in the received polynomial. - *
- * For a more complete picture on BCH decoding, see Shu. Lin and Daniel J. Costello in Error Control Coding: Fundamentals and Applications @cite lin1983error - * - * @param[out] message Array of size VEC_K_SIZE_BYTES receiving the decoded message - * @param[in] vector Array of size VEC_N1_SIZE_BYTES storing the received word - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector) { - uint16_t syndromes[1 << PARAM_FFT_T]; - uint16_t sigma[1 << PARAM_FFT] = {0}; - uint8_t error[(1 << PARAM_M) / 8] = {0}; - - // Calculate the 2*PARAM_DELTA syndromes - compute_syndromes(syndromes, vector); - - // Compute the error locator polynomial sigma - // Sigma's degree is at most PARAM_DELTA but the FFT requires the extra room - compute_elp(sigma, syndromes); - - // Compute the error polynomial error - compute_roots(error, sigma); - - // Add the error polynomial to the received polynomial - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(vector, vector, error, VEC_N1_SIZE_BYTES); - - // Retrieve the message from the decoded codeword - message_from_codeword(message, vector); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/bch.h b/crypto_kem/hqc-256-3-cca2/leaktime/bch.h deleted file mode 100644 index 4158b758..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/bch.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_BCH_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_BCH_H - -/** - * @file bch.h - * Header file of bch.c - */ - -#include "parameters.h" -#include -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_encode(uint8_t *codeword, const uint8_t *message); -void PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_decode(uint8_t *message, uint8_t *vector); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/fft.c b/crypto_kem/hqc-256-3-cca2/leaktime/fft.c deleted file mode 100644 index c04f5bb4..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/fft.c +++ /dev/null @@ -1,628 +0,0 @@ -/** - * @file fft.c - * Implementation of the additive FFT and its transpose. - * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - */ - -#include "fft.h" -#include "gf.h" -#include "parameters.h" -#include -#include - -static void compute_fft_betas(uint16_t *betas); -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size); -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f); -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f); -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, uint8_t m, uint32_t m_f, const uint16_t *betas); - - -/** - * @brief Computes the basis of betas (omitting 1) used in the additive FFT and its transpose - * - * @param[out] betas Array of size PARAM_M-1 - */ -static void compute_fft_betas(uint16_t *betas) { - for (size_t i = 0; i < PARAM_M - 1; ++i) { - betas[i] = 1 << (PARAM_M - 1 - i); - } -} - - - -/** - * @brief Computes the subset sums of the given set - * - * The array subset_sums is such that its ith element is - * the subset sum of the set elements given by the binary form of i. - * - * @param[out] subset_sums Array of size 2^set_size receiving the subset sums - * @param[in] set Array of set_size elements - * @param[in] set_size Size of the array set - */ -static void compute_subset_sums(uint16_t *subset_sums, const uint16_t *set, size_t set_size) { - subset_sums[0] = 0; - - for (size_t i = 0; i < set_size; ++i) { - for (size_t j = 0; j < (((size_t)1) << i); ++j) { - subset_sums[(((size_t)1) << i) + j] = set[i] ^ subset_sums[j]; - } - } -} - - - -/** - * @brief Transpose of the linear radix conversion - * - * This is a direct transposition of the radix function - * implemented following the process of transposing a linear function as exposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size a power of 2 - * @param[in] f0 Array half the size of f - * @param[in] f1 Array half the size of f - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix_t(uint16_t *f, const uint16_t *f0, const uint16_t *f1, uint32_t m_f) { - switch (m_f) { - case 4: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - f[8] = f[4] ^ f0[4]; - f[9] = f[5] ^ f1[4]; - f[10] = f[6] ^ f0[5] ^ f1[4]; - f[11] = f[7] ^ f0[5] ^ f1[4] ^ f1[5]; - f[12] = f[8] ^ f0[5] ^ f0[6] ^ f1[4]; - f[13] = f[7] ^ f[9] ^ f[11] ^ f1[6]; - f[14] = f[6] ^ f0[6] ^ f0[7] ^ f1[6]; - f[15] = f[7] ^ f0[7] ^ f1[7]; - return; - - case 3: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - f[4] = f[2] ^ f0[2]; - f[5] = f[3] ^ f1[2]; - f[6] = f[4] ^ f0[3] ^ f1[2]; - f[7] = f[3] ^ f0[3] ^ f1[3]; - return; - - case 2: - f[0] = f0[0]; - f[1] = f1[0]; - f[2] = f0[1] ^ f1[0]; - f[3] = f[2] ^ f1[1]; - return; - - case 1: - f[0] = f0[0]; - f[1] = f1[0]; - return; - - default: - ; - - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t Q1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t R1[1 << (PARAM_FFT_T - 2)] = {0}; - - uint16_t Q[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - uint16_t R[1 << 2 * (PARAM_FFT_T - 2)] = {0}; - - memcpy(Q0, f0 + n, 2 * n); - memcpy(Q1, f1 + n, 2 * n); - memcpy(R0, f0, 2 * n); - memcpy(R1, f1, 2 * n); - - radix_t (Q, Q0, Q1, m_f - 1); - radix_t (R, R0, R1, m_f - 1); - - memcpy(f, R, 4 * n); - memcpy(f + 2 * n, R + n, 2 * n); - memcpy(f + 3 * n, Q + n, 2 * n); - - for (size_t i = 0; i < n; ++i) { - f[2 * n + i] ^= Q[i]; - f[3 * n + i] ^= f[2 * n + i]; - } - } -} - - - -/** - * @brief Recursively computes syndromes of family w - * - * This function is a subroutine of the function fft_t - * - * @param[out] f Array receiving the syndromes - * @param[in] w Array storing the family - * @param[in] f_coeffs Length of syndromes vector - * @param[in] m 2^m is the smallest power of 2 greater or equal to the length of family w - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the length of f - * @param[in] betas FFT constants - */ -static void fft_t_rec(uint16_t *f, const uint16_t *w, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t f0[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT_T - 2)] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - - // Step 1 - if (m_f == 1) { - for (size_t i = 0; i < (((size_t)1) << m); ++i) { - f[0] ^= w[i]; - } - - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - size_t index = (((size_t)1) << j) + ki; - betas_sums[index] = betas_sums[ki] ^ betas[j]; - f[1] ^= PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas_sums[index], w[index]); - } - } - - return; - } - - // Compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2563CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas subset sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - /* Step 6: Compute u and v from w (aka w) - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - if (f_coeffs <= 3) { // 3-coefficient polynomial f case - // Step 5: Compute f0 from u and f1 from v - f1[1] = 0; - u[0] = w[0] ^ w[k]; - f1[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - f1[0] ^= PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - } else { - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(gammas_sums[i], u[i]) ^ w[k + i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, m - 1, m_f - 1, deltas); - } - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, m_f); - - // Step 2: compute f from g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } -} - - - -/** - * @brief Computes the syndromes f of the family w - * - * Since the syndromes linear map is the transpose of multipoint evaluation, - * it uses exactly the same constants, either hardcoded or precomputed by compute_fft_lut(...).
- * This follows directives from Bernstein, Chou and Schwabe given here: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f Array of size 2*(PARAM_FFT_T) elements receiving the syndromes - * @param[in] w Array of PARAM_GF_MUL_ORDER+1 elements - * @param[in] f_coeffs Length of syndromes vector f - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs) { - // Transposed from Gao and Mateer algorithm - uint16_t betas[PARAM_M - 1]; - uint16_t betas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - uint16_t f0[1 << (PARAM_FFT_T - 1)]; - uint16_t f1[1 << (PARAM_FFT_T - 1)]; - - compute_fft_betas(betas); - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - /* Step 6: Compute u and v from w (aka w) - * - * We had: - * w[i] = u[i] + G[i].v[i] - * w[k+i] = w[i] + v[i] = u[i] + (G[i]+1).v[i] - * Transpose: - * u[i] = w[i] + w[k+i] - * v[i] = G[i].w[i] + (G[i]+1).w[k+i] = G[i].u[i] + w[k+i] */ - u[0] = w[0] ^ w[k]; - v[0] = w[k]; - for (size_t i = 1; i < k; ++i) { - u[i] = w[i] ^ w[k + i]; - v[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas_sums[i], u[i]) ^ w[k + i]; - } - - // Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5: Compute f0 from u and f1 from v - fft_t_rec(f0, u, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - fft_t_rec(f1, v, f_coeffs / 2, PARAM_M - 1, PARAM_FFT_T - 1, deltas); - - // Step 3: Compute g from g0 and g1 - radix_t(f, f0, f1, PARAM_FFT_T); - - // Step 2: beta_m = 1 so f = g -} - - - -/** - * @brief Computes the radix conversion of a polynomial f in GF(2^m)[x] - * - * Computes f0 and f1 such that f(x) = f0(x^2-x) + x.f1(x^2-x) - * as proposed by Bernstein, Chou and Schwabe: - * https://binary.cr.yp.to/mcbits-20130616.pdf - * - * @param[out] f0 Array half the size of f - * @param[out] f1 Array half the size of f - * @param[in] f Array of size a power of 2 - * @param[in] m_f 2^{m_f} is the smallest power of 2 greater or equal to the number of coefficients of f - */ -static void radix(uint16_t *f0, uint16_t *f1, const uint16_t *f, uint32_t m_f) { - switch (m_f) { - case 4: - f0[4] = f[8] ^ f[12]; - f0[6] = f[12] ^ f[14]; - f0[7] = f[14] ^ f[15]; - f1[5] = f[11] ^ f[13]; - f1[6] = f[13] ^ f[14]; - f1[7] = f[15]; - f0[5] = f[10] ^ f[12] ^ f1[5]; - f1[4] = f[9] ^ f[13] ^ f0[5]; - - f0[0] = f[0]; - f1[3] = f[7] ^ f[11] ^ f[15]; - f0[3] = f[6] ^ f[10] ^ f[14] ^ f1[3]; - f0[2] = f[4] ^ f0[4] ^ f0[3] ^ f1[3]; - f1[1] = f[3] ^ f[5] ^ f[9] ^ f[13] ^ f1[3]; - f1[2] = f[3] ^ f1[1] ^ f0[3]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 3: - f0[0] = f[0]; - f0[2] = f[4] ^ f[6]; - f0[3] = f[6] ^ f[7]; - f1[1] = f[3] ^ f[5] ^ f[7]; - f1[2] = f[5] ^ f[6]; - f1[3] = f[7]; - f0[1] = f[2] ^ f0[2] ^ f1[1]; - f1[0] = f[1] ^ f0[1]; - return; - - case 2: - f0[0] = f[0]; - f0[1] = f[2] ^ f[3]; - f1[0] = f[1] ^ f0[1]; - f1[1] = f[3]; - return; - - case 1: - f0[0] = f[0]; - f1[0] = f[1]; - return; - - default: - ; - size_t n = ((size_t)1) << (m_f - 2); - - uint16_t Q[2 * (1 << (PARAM_FFT - 2))]; - uint16_t R[2 * (1 << (PARAM_FFT - 2))]; - - uint16_t Q0[1 << (PARAM_FFT - 2)]; - uint16_t Q1[1 << (PARAM_FFT - 2)]; - uint16_t R0[1 << (PARAM_FFT - 2)]; - uint16_t R1[1 << (PARAM_FFT - 2)]; - - memcpy(Q, f + 3 * n, 2 * n); - memcpy(Q + n, f + 3 * n, 2 * n); - memcpy(R, f, 4 * n); - - for (size_t i = 0; i < n; ++i) { - Q[i] ^= f[2 * n + i]; - R[n + i] ^= Q[i]; - } - - radix(Q0, Q1, Q, m_f - 1); - radix(R0, R1, R, m_f - 1); - - memcpy(f0, R0, 2 * n); - memcpy(f0 + n, Q0, 2 * n); - memcpy(f1, R1, 2 * n); - memcpy(f1 + n, Q1, 2 * n); - } -} - - - -/** - * @brief Evaluates f at all subset sums of a given set - * - * This function is a subroutine of the function fft. - * - * @param[out] w Array - * @param[in] f Array - * @param[in] f_coeffs Number of coefficients of f - * @param[in] m Number of betas - * @param[in] m_f Number of coefficients of f (one more than its degree) - * @param[in] betas FFT constants - */ -static void fft_rec(uint16_t *w, uint16_t *f, size_t f_coeffs, - uint8_t m, uint32_t m_f, const uint16_t *betas) { - - uint16_t f0[1 << (PARAM_FFT - 2)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 2)] = {0}; - uint16_t gammas[PARAM_M - 2] = {0}; - uint16_t deltas[PARAM_M - 2] = {0}; - size_t k = ((size_t)1) << (m - 1); - uint16_t gammas_sums[1 << (PARAM_M - 2)] = {0}; - uint16_t u[1 << (PARAM_M - 2)] = {0}; - uint16_t v[1 << (PARAM_M - 2)] = {0}; - - // Step 1 - if (m_f == 1) { - uint16_t tmp[PARAM_M - (PARAM_FFT - 1)]; - for (size_t i = 0; i < m; ++i) { - tmp[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas[i], f[1]); - } - - w[0] = f[0]; - for (size_t j = 0; j < m; ++j) { - for (size_t ki = 0; ki < (((size_t)1) << j); ++ki) { - w[(((size_t)1) << j) + ki] = w[ki] ^ tmp[j]; - } - } - - return; - } - - // Step 2: compute g - if (betas[m - 1] != 1) { - uint16_t beta_m_pow = 1; - for (size_t i = 1; i < (((size_t)1) << m_f); ++i) { - beta_m_pow = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(beta_m_pow, betas[m - 1]); - f[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(beta_m_pow, f[i]); - } - } - - // Step 3 - radix(f0, f1, f, m_f); - - // Step 4: compute gammas and deltas - for (uint8_t i = 0; i < m - 1; ++i) { - gammas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas[i], PQCLEAN_HQC2563CCA2_LEAKTIME_gf_inverse(betas[m - 1])); - deltas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(gammas[i]) ^ gammas[i]; - } - - // Compute gammas sums - compute_subset_sums(gammas_sums, gammas, m - 1); - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, m - 1, m_f - 1, deltas); - - if (f_coeffs <= 3) { // 3-coefficient polynomial f case: f1 is constant - w[0] = u[0]; - w[k] = u[0] ^ f1[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(gammas_sums[i], f1[0]); - w[k + i] = w[i] ^ f1[0]; - } - } else { - fft_rec(v, f1, f_coeffs / 2, m - 1, m_f - 1, deltas); - - // Step 6 - memcpy(w + k, v, 2 * k); - w[0] = u[0]; - w[k] ^= u[0]; - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(gammas_sums[i], v[i]); - w[k + i] ^= w[i]; - } - } -} - - - -/** - * @brief Evaluates f on all fields elements using an additive FFT algorithm - * - * f_coeffs is the number of coefficients of f (one less than its degree).
- * The FFT proceeds recursively to evaluate f at all subset sums of a basis B.
- * This implementation is based on the paper from Gao and Mateer:
- * Shuhong Gao and Todd Mateer, Additive Fast Fourier Transforms over Finite Fields, - * IEEE Transactions on Information Theory 56 (2010), 6265--6272. - * http://www.math.clemson.edu/~sgao/papers/GM10.pdf
- * and includes improvements proposed by Bernstein, Chou and Schwabe here: - * https://binary.cr.yp.to/mcbits-20130616.pdf
- * Constants betas, gammas and deltas involved in the algorithm are either hardcoded or precomputed - * by the subroutine compute_fft_lut(...).
- * Note that on this first call (as opposed to the recursive calls to fft_rec), gammas are equal to betas, - * meaning the first gammas subset sums are actually the subset sums of betas (except 1).
- * Also note that f is altered during computation (twisted at each level). - * - * @param[out] w Array - * @param[in] f Array of 2^PARAM_FFT elements - * @param[in] f_coeffs Number coefficients of f (i.e. deg(f)+1) - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs) { - uint16_t betas[PARAM_M - 1] = {0}; - uint16_t betas_sums[1 << (PARAM_M - 1)] = {0}; - uint16_t f0[1 << (PARAM_FFT - 1)] = {0}; - uint16_t f1[1 << (PARAM_FFT - 1)] = {0}; - uint16_t deltas[PARAM_M - 1]; - size_t k = 1 << (PARAM_M - 1); - uint16_t u[1 << (PARAM_M - 1)] = {0}; - uint16_t v[1 << (PARAM_M - 1)] = {0}; - - // Follows Gao and Mateer algorithm - compute_fft_betas(betas); - - // Step 1: PARAM_FFT > 1, nothing to do - - // Compute gammas sums - compute_subset_sums(betas_sums, betas, PARAM_M - 1); - - // Step 2: beta_m = 1, nothing to do - - // Step 3 - radix(f0, f1, f, PARAM_FFT); - - // Step 4: Compute deltas - for (size_t i = 0; i < PARAM_M - 1; ++i) { - deltas[i] = PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(betas[i]) ^ betas[i]; - } - - // Step 5 - fft_rec(u, f0, (f_coeffs + 1) / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - fft_rec(v, f1, f_coeffs / 2, PARAM_M - 1, PARAM_FFT - 1, deltas); - - // Step 6, 7 and error polynomial computation - memcpy(w + k, v, 2 * k); - - // Check if 0 is root - w[0] = u[0]; - - // Check if 1 is root - w[k] ^= u[0]; - - // Find other roots - for (size_t i = 1; i < k; ++i) { - w[i] = u[i] ^ PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(betas_sums[i], v[i]); - w[k + i] ^= w[i]; - } -} - - - -/** - * @brief Arranges the received word vector in a form w such that applying the additive FFT transpose to w yields the BCH syndromes of the received word vector. - * - * Since the received word vector gives coefficients of the primitive element alpha, we twist accordingly.
- * Furthermore, the additive FFT transpose needs elements indexed by their decomposition on the chosen basis, - * so we apply the adequate permutation. - * - * @param[out] w Array of size 2^PARAM_M - * @param[in] vector Array of size VEC_N1_SIZE_BYTES - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector) { - uint16_t r[1 << PARAM_M]; - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - - // Unpack the received word vector into array r - size_t i; - for (i = 0; i < VEC_N1_SIZE_BYTES - (PARAM_N1 % 8 != 0); ++i) { - for (size_t j = 0; j < 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - } - - // Last byte - for (size_t j = 0; j < PARAM_N1 % 8; ++j) { - r[8 * i + j] = (vector[i] >> j) & 1; - } - - // Complete r with zeros - memset(r + PARAM_N1, 0, 2 * ((1 << PARAM_M) - PARAM_N1)); - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - // Twist and permute r adequately to obtain w - w[0] = 0; - w[k] = -r[0] & 1; - for (i = 1; i < k; ++i) { - w[i] = -r[PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(gammas_sums[i])] & gammas_sums[i]; - w[k + i] = -r[PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1)] & (gammas_sums[i] ^ 1); - } -} - - - -/** - * @brief Retrieves the error polynomial error from the evaluations w of the ELP (Error Locator Polynomial) on all field elements. - * - * @param[out] error Array of size VEC_N1_SIZE_BYTES - * @param[in] w Array of size 2^PARAM_M - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w) { - uint16_t gammas[PARAM_M - 1]; - uint16_t gammas_sums[1 << (PARAM_M - 1)]; - size_t k = 1 << (PARAM_M - 1); - size_t index = PARAM_GF_MUL_ORDER; - - compute_fft_betas(gammas); - compute_subset_sums(gammas_sums, gammas, PARAM_M - 1); - - error[0] ^= 1 ^ ((uint16_t) - w[0] >> 15); - uint8_t bit = 1 ^ ((uint16_t) - w[k] >> 15); - error[index / 8] ^= bit << (index % 8); - - for (size_t i = 1; i < k; ++i) { - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(gammas_sums[i]); - bit = 1 ^ ((uint16_t) - w[i] >> 15); - error[index / 8] ^= bit << (index % 8); - - index = PARAM_GF_MUL_ORDER - PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(gammas_sums[i] ^ 1); - bit = 1 ^ ((uint16_t) - w[k + i] >> 15); - error[index / 8] ^= bit << (index % 8); - } -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/fft.h b/crypto_kem/hqc-256-3-cca2/leaktime/fft.h deleted file mode 100644 index bba57af7..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/fft.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_FFT_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_FFT_H - -/** - * @file fft.h - * Header file of fft.c - */ - -#include -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t(uint16_t *f, const uint16_t *w, size_t f_coeffs); -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_t_preprocess_bch_codeword(uint16_t *w, const uint8_t *vector); - -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft(uint16_t *w, const uint16_t *f, size_t f_coeffs); -void PQCLEAN_HQC2563CCA2_LEAKTIME_fft_retrieve_bch_error_poly(uint8_t *error, const uint16_t *w); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/gf.c b/crypto_kem/hqc-256-3-cca2/leaktime/gf.c deleted file mode 100644 index 2c58abb8..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/gf.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file gf.c - * Galois field implementation with multiplication using lookup tables - */ - -#include "gf.h" -#include "parameters.h" -#include - - -/** - * Powers of the root alpha of x^10 + x^3 + 1. - * The last two elements are needed by the gf_mul function from gf_lutmul.c - * (for example if both elements to multiply are zero). - */ -static const uint16_t exptable[1026] = { - 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 9, 18, 36, 72, 144, 288, 576, 137, 274, 548, 65, 130, 260, 520, 25, 50, 100, 200, 400, 800, 585, 155, 310, 620, 209, 418, 836, 641, 267, 534, 37, 74, 148, 296, 592, 169, 338, 676, 321, 642, 269, 538, 61, 122, 244, 488, 976, 937, 859, 703, 375, 750, 469, 938, 861, 691, 367, 734, 437, 874, 733, 435, 870, 709, 387, 774, 517, 3, 6, 12, 24, 48, 96, 192, 384, 768, 521, 27, 54, 108, 216, 432, 864, 713, 411, 822, 613, 195, 390, 780, 529, 43, 86, 172, 344, 688, 361, 722, 429, 858, 701, 371, 742, 453, 906, 797, 563, 111, 222, 444, 888, 761, 507, 1014, 997, 963, 911, 791, 551, 71, 142, 284, 568, 121, 242, 484, 968, 921, 827, 639, 247, 494, 988, 945, 875, 735, 439, 878, 725, 419, 838, 645, 259, 518, 5, 10, 20, 40, 80, 160, 320, 640, 265, 530, 45, 90, 180, 360, 720, 425, 850, 685, 339, 678, 325, 650, 285, 570, 125, 250, 500, 1000, 985, 955, 895, 759, 487, 974, 917, 803, 591, 151, 302, 604, 177, 354, 708, 385, 770, 525, 19, 38, 76, 152, 304, 608, 201, 402, 804, 577, 139, 278, 556, 81, 162, 324, 648, 281, 562, 109, 218, 436, 872, 729, 443, 886, 741, 451, 902, 773, 515, 15, 30, 60, 120, 240, 480, 960, 905, 795, 575, 119, 238, 476, 952, 889, 763, 511, 1022, 1013, 995, 975, 919, 807, 583, 135, 270, 540, 49, 98, 196, 392, 784, 553, 91, 182, 364, 728, 441, 882, 749, 467, 934, 837, 643, 271, 542, 53, 106, 212, 424, 848, 681, 347, 694, 357, 714, 413, 826, 637, 243, 486, 972, 913, 811, 607, 183, 366, 732, 433, 866, 717, 403, 806, 581, 131, 262, 524, 17, 34, 68, 136, 272, 544, 73, 146, 292, 584, 153, 306, 612, 193, 386, 772, 513, 11, 22, 44, 88, 176, 352, 704, 393, 786, 557, 83, 166, 332, 664, 313, 626, 237, 474, 948, 865, 715, 415, 830, 629, 227, 454, 908, 785, 555, 95, 190, 380, 760, 505, 1010, 1005, 979, 943, 855, 679, 327, 654, 277, 554, 93, 186, 372, 744, 473, 946, 877, 723, 431, 862, 693, 355, 710, 389, 778, 541, 51, 102, 204, 408, 816, 617, 219, 438, 876, 721, 427, 854, 677, 323, 646, 261, 522, 29, 58, 116, 232, 464, 928, 841, 667, 319, 638, 245, 490, 980, 929, 843, 671, 311, 622, 213, 426, 852, 673, 331, 662, 293, 586, 157, 314, 628, 225, 450, 900, 769, 523, 31, 62, 124, 248, 496, 992, 969, 923, 831, 631, 231, 462, 924, 817, 619, 223, 446, 892, 753, 491, 982, 933, 835, 655, 279, 558, 85, 170, 340, 680, 345, 690, 365, 730, 445, 890, 765, 499, 998, 965, 899, 783, 535, 39, 78, 156, 312, 624, 233, 466, 932, 833, 651, 287, 574, 117, 234, 468, 936, 857, 699, 383, 766, 501, 1002, 989, 947, 879, 727, 423, 846, 661, 291, 582, 133, 266, 532, 33, 66, 132, 264, 528, 41, 82, 164, 328, 656, 297, 594, 173, 346, 692, 353, 706, 397, 794, 573, 115, 230, 460, 920, 825, 635, 255, 510, 1020, 1009, 1003, 991, 951, 871, 711, 391, 782, 533, 35, 70, 140, 280, 560, 105, 210, 420, 840, 665, 315, 630, 229, 458, 916, 801, 587, 159, 318, 636, 241, 482, 964, 897, 779, 543, 55, 110, 220, 440, 880, 745, 475, 950, 869, 707, 399, 798, 565, 99, 198, 396, 792, 569, 123, 246, 492, 984, 953, 891, 767, 503, 1006, 981, 931, 847, 663, 295, 590, 149, 298, 596, 161, 322, 644, 257, 514, 13, 26, 52, 104, 208, 416, 832, 649, 283, 566, 101, 202, 404, 808, 601, 187, 374, 748, 465, 930, 845, 659, 303, 606, 181, 362, 724, 417, 834, 653, 275, 550, 69, 138, 276, 552, 89, 178, 356, 712, 409, 818, 621, 211, 422, 844, 657, 299, 598, 165, 330, 660, 289, 578, 141, 282, 564, 97, 194, 388, 776, 537, 59, 118, 236, 472, 944, 873, 731, 447, 894, 757, 483, 966, 901, 771, 527, 23, 46, 92, 184, 368, 736, 457, 914, 813, 595, 175, 350, 700, 369, 738, 461, 922, 829, 627, 239, 478, 956, 881, 747, 479, 958, 885, 739, 463, 926, 821, 611, 207, 414, 828, 625, 235, 470, 940, 849, 683, 351, 702, 373, 746, 477, 954, 893, 755, 495, 990, 949, 867, 719, 407, 814, 597, 163, 326, 652, 273, 546, 77, 154, 308, 616, 217, 434, 868, 705, 395, 790, 549, 67, 134, 268, 536, 57, 114, 228, 456, 912, 809, 603, 191, 382, 764, 497, 994, 973, 915, 815, 599, 167, 334, 668, 305, 610, 205, 410, 820, 609, 203, 406, 812, 593, 171, 342, 684, 337, 674, 333, 666, 317, 634, 253, 506, 1012, 993, 971, 927, 823, 615, 199, 398, 796, 561, 107, 214, 428, 856, 697, 379, 758, 485, 970, 925, 819, 623, 215, 430, 860, 689, 363, 726, 421, 842, 669, 307, 614, 197, 394, 788, 545, 75, 150, 300, 600, 185, 370, 740, 449, 898, 781, 531, 47, 94, 188, 376, 752, 489, 978, 941, 851, 687, 343, 686, 341, 682, 349, 698, 381, 762, 509, 1018, 1021, 1011, 1007, 983, 935, 839, 647, 263, 526, 21, 42, 84, 168, 336, 672, 329, 658, 301, 602, 189, 378, 756, 481, 962, 909, 787, 559, 87, 174, 348, 696, 377, 754, 493, 986, 957, 883, 751, 471, 942, 853, 675, 335, 670, 309, 618, 221, 442, 884, 737, 459, 918, 805, 579, 143, 286, 572, 113, 226, 452, 904, 793, 571, 127, 254, 508, 1016, 1017, 1019, 1023, 1015, 999, 967, 903, 775, 519, 7, 14, 28, 56, 112, 224, 448, 896, 777, 539, 63, 126, 252, 504, 1008, 1001, 987, 959, 887, 743, 455, 910, 789, 547, 79, 158, 316, 632, 249, 498, 996, 961, 907, 799, 567, 103, 206, 412, 824, 633, 251, 502, 1004, 977, 939, 863, 695, 359, 718, 405, 810, 605, 179, 358, 716, 401, 802, 589, 147, 294, 588, 145, 290, 580, 129, 258, 516, 1, 2, 4 -}; - - - -/** - * Logarithm of elements of GF(2^10) to the base alpha (root of x^10 + x^3 + 1). - * The logarithm of 0 is set to 1024 by convention. - */ -static const uint16_t logtable[1024] = { - 1024, 0, 1, 77, 2, 154, 78, 956, 3, 10, 155, 325, 79, 618, 957, 231, 4, 308, 11, 200, 156, 889, 326, 695, 80, 24, 619, 87, 958, 402, 232, 436, 5, 513, 309, 551, 12, 40, 201, 479, 157, 518, 890, 101, 327, 164, 696, 860, 81, 258, 25, 385, 620, 277, 88, 577, 959, 772, 403, 680, 233, 52, 437, 966, 6, 20, 514, 768, 310, 650, 552, 129, 13, 314, 41, 849, 202, 757, 480, 980, 158, 213, 519, 335, 891, 462, 102, 907, 328, 654, 165, 264, 697, 369, 861, 354, 82, 675, 259, 590, 26, 628, 386, 991, 621, 556, 278, 822, 89, 219, 578, 117, 960, 937, 773, 533, 404, 491, 681, 241, 234, 133, 53, 595, 438, 178, 967, 943, 7, 1020, 21, 305, 515, 510, 769, 255, 311, 17, 651, 210, 553, 672, 130, 934, 14, 1017, 315, 1014, 42, 610, 850, 191, 203, 318, 758, 31, 481, 428, 981, 568, 159, 613, 214, 752, 520, 667, 336, 788, 892, 45, 463, 801, 103, 525, 908, 705, 329, 194, 655, 1008, 166, 642, 265, 296, 698, 853, 370, 633, 862, 899, 355, 779, 83, 321, 676, 97, 260, 845, 591, 818, 27, 206, 629, 797, 387, 793, 992, 727, 622, 34, 557, 661, 279, 420, 823, 834, 90, 761, 220, 391, 579, 926, 118, 451, 961, 431, 938, 349, 774, 563, 534, 446, 405, 484, 492, 731, 682, 341, 242, 714, 235, 571, 134, 290, 54, 412, 596, 140, 439, 984, 179, 996, 968, 810, 944, 539, 8, 616, 1021, 152, 22, 400, 306, 887, 516, 162, 511, 38, 770, 50, 256, 275, 312, 755, 18, 648, 652, 367, 211, 460, 554, 217, 673, 626, 131, 176, 935, 489, 15, 670, 1018, 508, 316, 426, 1015, 608, 43, 523, 611, 665, 851, 897, 192, 640, 204, 791, 319, 843, 759, 924, 32, 418, 482, 339, 429, 561, 982, 808, 569, 410, 160, 48, 614, 398, 215, 174, 753, 365, 521, 895, 668, 424, 337, 806, 789, 922, 893, 804, 46, 172, 464, 872, 802, 870, 104, 466, 526, 283, 909, 874, 706, 736, 330, 528, 195, 380, 656, 285, 1009, 1003, 167, 106, 643, 838, 266, 468, 297, 66, 699, 708, 854, 111, 371, 738, 634, 60, 863, 911, 900, 827, 356, 876, 780, 497, 84, 197, 322, 74, 677, 382, 98, 548, 261, 332, 846, 765, 592, 530, 819, 587, 28, 1011, 207, 302, 630, 1005, 798, 749, 388, 658, 794, 94, 993, 287, 728, 346, 623, 645, 35, 149, 558, 840, 662, 505, 280, 169, 421, 395, 824, 108, 835, 377, 91, 299, 762, 71, 221, 68, 392, 146, 580, 268, 927, 224, 119, 470, 452, 687, 962, 856, 432, 227, 939, 113, 350, 976, 775, 701, 564, 930, 535, 710, 447, 723, 406, 636, 485, 271, 493, 62, 732, 918, 683, 373, 342, 583, 243, 740, 715, 719, 236, 902, 572, 690, 135, 829, 291, 186, 55, 865, 413, 455, 597, 913, 141, 744, 440, 782, 985, 473, 180, 499, 997, 602, 969, 358, 811, 122, 945, 878, 540, 247, 9, 324, 617, 230, 1022, 76, 153, 955, 23, 86, 401, 435, 307, 199, 888, 694, 517, 100, 163, 859, 512, 550, 39, 478, 771, 679, 51, 965, 257, 384, 276, 576, 313, 848, 756, 979, 19, 767, 649, 128, 653, 263, 368, 353, 212, 334, 461, 906, 555, 821, 218, 116, 674, 589, 627, 990, 132, 594, 177, 942, 936, 532, 490, 240, 16, 209, 671, 933, 1019, 304, 509, 254, 317, 30, 427, 567, 1016, 1013, 609, 190, 44, 800, 524, 704, 612, 751, 666, 787, 852, 632, 898, 778, 193, 1007, 641, 295, 205, 796, 792, 726, 320, 96, 844, 817, 760, 390, 925, 450, 33, 660, 419, 833, 483, 730, 340, 713, 430, 348, 562, 445, 983, 995, 809, 538, 570, 289, 411, 139, 161, 37, 49, 274, 615, 151, 399, 886, 216, 625, 175, 488, 754, 647, 366, 459, 522, 664, 896, 639, 669, 507, 425, 607, 338, 560, 807, 409, 790, 842, 923, 417, 894, 423, 805, 921, 47, 397, 173, 364, 465, 282, 873, 735, 803, 171, 871, 869, 105, 837, 467, 65, 527, 379, 284, 1002, 910, 826, 875, 496, 707, 110, 737, 59, 331, 764, 529, 586, 196, 73, 381, 547, 657, 93, 286, 345, 1010, 301, 1004, 748, 168, 394, 107, 376, 644, 148, 839, 504, 267, 223, 469, 686, 298, 70, 67, 145, 700, 929, 709, 722, 855, 226, 112, 975, 372, 582, 739, 718, 635, 270, 61, 917, 864, 454, 912, 743, 901, 689, 828, 185, 357, 121, 877, 246, 781, 472, 498, 601, 85, 434, 198, 693, 323, 229, 75, 954, 678, 964, 383, 575, 99, 858, 549, 477, 262, 352, 333, 905, 847, 978, 766, 127, 593, 941, 531, 239, 820, 115, 588, 989, 29, 566, 1012, 189, 208, 932, 303, 253, 631, 777, 1006, 294, 799, 703, 750, 786, 389, 449, 659, 832, 795, 725, 95, 816, 994, 537, 288, 138, 729, 712, 347, 444, 624, 487, 646, 458, 36, 273, 150, 885, 559, 408, 841, 416, 663, 638, 506, 606, 281, 734, 170, 868, 422, 920, 396, 363, 825, 495, 109, 58, 836, 64, 378, 1001, 92, 344, 300, 747, 763, 585, 72, 546, 222, 685, 69, 144, 393, 375, 147, 503, 581, 717, 269, 916, 928, 721, 225, 974, 120, 245, 471, 600, 453, 742, 688, 184, 963, 574, 857, 476, 433, 692, 228, 953, 940, 238, 114, 988, 351, 904, 977, 126, 776, 293, 702, 785, 565, 188, 931, 252, 536, 137, 711, 443, 448, 831, 724, 815, 407, 415, 637, 605, 486, 457, 272, 884, 494, 57, 63, 1000, 733, 867, 919, 362, 684, 143, 374, 502, 343, 746, 584, 545, 244, 599, 741, 183, 716, 915, 720, 973, 237, 987, 903, 125, 573, 475, 691, 952, 136, 442, 830, 814, 292, 784, 187, 251, 56, 999, 866, 361, 414, 604, 456, 883, 598, 182, 914, 972, 142, 501, 745, 544, 441, 813, 783, 250, 986, 124, 474, 951, 181, 971, 500, 543, 998, 360, 603, 882, 970, 542, 359, 881, 812, 249, 123, 950, 946, 947, 879, 948, 541, 880, 248, 949 -}; - - - -/** - * @brief Returns the integer i such that elt = a^i where a is the primitive element of GF(2^PARAM_M). - * - * @returns the logarithm of the given element - */ -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(uint16_t elt) { - return logtable[elt]; -} - - - -/** - * @brief Multiplies nonzero element a by element b - * - * @returns the product a*b - * @param[in] a First element of GF(2^PARAM_M) to multiply (cannot be zero) - * @param[in] b Second element of GF(2^PARAM_M) to multiply (cannot be zero) - */ -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b) { - // mask = 0xffff if neither a nor b is zero. Otherwise mask is 0. - int16_t mask = ((logtable[a] | logtable[b]) >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mod(logtable[a] + logtable[b])]; -} - - - -/** - * @brief Squares an element of GF(2^PARAM_M) - * - * @returns a^2 - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(uint16_t a) { - int16_t mask = (logtable[a] >> PARAM_M) - 1; - return mask & exptable[PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mod(2 * logtable[a])]; -} - - - -/** - * @brief Computes the inverse of an element of GF(2^PARAM_M) - * - * @returns the inverse of a - * @param[in] a Element of GF(2^PARAM_M) - */ -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_inverse(uint16_t a) { - return exptable[PARAM_GF_MUL_ORDER - logtable[a]]; -} - - - -/** - * @brief Returns i modulo 2^PARAM_M-1 - * - * i must be less than 2*(2^PARAM_M-1). - * Therefore, the return value is either i or i-2^PARAM_M+1. - * - * @returns i mod (2^PARAM_M-1) - * @param[in] i The integer whose modulo is taken - */ -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mod(uint16_t i) { - uint16_t tmp = i - PARAM_GF_MUL_ORDER; - - // mask = 0xffff if(i < PARAM_GF_MUL_ORDER) - int16_t mask = -(tmp >> 15); - - return tmp + (mask & PARAM_GF_MUL_ORDER); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/gf.h b/crypto_kem/hqc-256-3-cca2/leaktime/gf.h deleted file mode 100644 index 81bbae8f..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/gf.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_GF_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_GF_H - -/** - * @file gf.h - * Header file of gf.c - */ - -#include -#include - -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_log(uint16_t elt); -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mul(uint16_t a, uint16_t b); -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_square(uint16_t a); -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_inverse(uint16_t a); -uint16_t PQCLEAN_HQC2563CCA2_LEAKTIME_gf_mod(uint16_t i); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.c b/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.c deleted file mode 100644 index 25936aab..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * \file gf2x.c - * \brief Implementation of multiplication of two polynomials - */ - -#include "gf2x.h" -#include "parameters.h" -#include "util.h" - -#include -#include - -#define WORD_TYPE uint64_t -#define WORD_TYPE_BITS (sizeof(WORD_TYPE) * 8) -#define UTILS_VECTOR_ARRAY_SIZE CEIL_DIVIDE(PARAM_N, WORD_TYPE_BITS) - -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v); - - -/** - * @brief A subroutine used in the function sparse_dense_mul() - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - * @return 0 if precomputation is successful, -1 otherwise - */ -static int vect_mul_precompute_rows(WORD_TYPE *o, const WORD_TYPE *v) { - int8_t var; - for (size_t i = 0; i < PARAM_N; ++i) { - var = 0; - - // All the bits that we need are in the same block - if (((i % WORD_TYPE_BITS) == 0) && (i != PARAM_N - (PARAM_N % WORD_TYPE_BITS))) { - var = 1; - } - - // Cases where the bits are in before the last block, the last block and the first block - if (i > PARAM_N - WORD_TYPE_BITS) { - if (i >= PARAM_N - (PARAM_N % WORD_TYPE_BITS)) { - var = 2; - } else { - var = 3; - } - } - - switch (var) { - case 0: - // Take bits in the last block and the first one - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - break; - - case 1: - o[i] = v[i / WORD_TYPE_BITS]; - break; - - case 2: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[0] << ((PARAM_N - i) % WORD_TYPE_BITS); - break; - - case 3: - o[i] = 0; - o[i] += v[i / WORD_TYPE_BITS] >> (i % WORD_TYPE_BITS); - o[i] += v[(i / WORD_TYPE_BITS) + 1] << (WORD_TYPE_BITS - (i % WORD_TYPE_BITS)); - o[i] += v[0] << ((WORD_TYPE_BITS - i + (PARAM_N % WORD_TYPE_BITS)) % WORD_TYPE_BITS); - break; - - default: - return -1; - } - } - - return 0; -} - - - -/** - * @brief Multiplies two vectors - * - * This function multiplies two vectors: a sparse vector of Hamming weight equal to weight and a dense (random) vector. - * The vector a1 is the sparse vector and a2 is the dense vector. - * We notice that the idea is explained using vector of 32 bits elements instead of 64 (the algorithm works in booth cases). - * - * @param[out] o Pointer to a vector that is the result of the multiplication - * @param[in] a1 Pointer to the sparse vector stored by position - * @param[in] a2 Pointer to the dense vector - * @param[in] weight Integer that is the weight of the sparse vector - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight) { - WORD_TYPE v1[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE res[UTILS_VECTOR_ARRAY_SIZE] = {0}; - WORD_TYPE precomputation_array [PARAM_N] = {0}; - WORD_TYPE row [UTILS_VECTOR_ARRAY_SIZE] = {0}; - uint32_t index; - - PQCLEAN_HQC2563CCA2_LEAKTIME_load8_arr(v1, UTILS_VECTOR_ARRAY_SIZE, a2, VEC_N_SIZE_BYTES); - vect_mul_precompute_rows(precomputation_array, v1); - - for (size_t i = 0; i < weight; ++i) { - int32_t k = UTILS_VECTOR_ARRAY_SIZE; - - for (size_t j = 0; j < UTILS_VECTOR_ARRAY_SIZE - 1; ++j) { - index = WORD_TYPE_BITS * (uint32_t)j - a1[i]; - if (index > PARAM_N) { - index += PARAM_N; - } - row[j] = precomputation_array[index]; - } - - index = WORD_TYPE_BITS * (UTILS_VECTOR_ARRAY_SIZE - 1) - a1[i]; - row[UTILS_VECTOR_ARRAY_SIZE - 1] = precomputation_array[(index < PARAM_N ? index : index + PARAM_N)] & BITMASK(PARAM_N, WORD_TYPE_BITS); - - while (k--) { - res[k] ^= row[k]; - } - } - - PQCLEAN_HQC2563CCA2_LEAKTIME_store8_arr(o, VEC_N_SIZE_BYTES, res, UTILS_VECTOR_ARRAY_SIZE); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.h b/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.h deleted file mode 100644 index 69812708..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/gf2x.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_GF2X_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_GF2X_H - -/** - * @file gf2x.h - * @brief Header file for gf2x.c - */ - -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(uint8_t *o, const uint32_t *a1, const uint8_t *a2, uint16_t weight); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/hqc.c b/crypto_kem/hqc-256-3-cca2/leaktime/hqc.c deleted file mode 100644 index b017b3f8..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/hqc.c +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @file hqc.c - * @brief Implementation of hqc.h - */ - -#include "gf2x.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "randombytes.h" -#include "tensor.h" -#include "vector.h" -#include - - -/** - * @brief Keygen of the HQC_PKE IND_CPA scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - AES_XOF_struct pk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - uint8_t pk_seed[SEED_BYTES] = {0}; - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expanders for public key and secret key - randombytes(sk_seed, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - randombytes(pk_seed, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - // Compute secret key - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - - // Compute public key - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(s, y, h, PARAM_OMEGA); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(s, x, s, VEC_N_SIZE_BYTES); - - // Parse keys to string - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_to_string(pk, pk_seed, s); - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_to_string(sk, sk_seed, pk); -} - - - -/** - * @brief Encryption of the HQC_PKE IND_CPA scheme - * - * The cihertext is composed of vectors u and v. - * - * @param[out] u Vector u (first part of the ciphertext) - * @param[out] v Vector v (second part of the ciphertext) - * @param[in] m Vector representing the message to encrypt - * @param[in] theta Seed used to derive randomness required for encryption - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk) { - AES_XOF_struct seedexpander; - uint8_t h[VEC_N_SIZE_BYTES] = {0}; - uint8_t s[VEC_N_SIZE_BYTES] = {0}; - uint8_t r1[VEC_N_SIZE_BYTES] = {0}; - uint32_t r2[PARAM_OMEGA_R] = {0}; - uint8_t e[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Create seed_expander from theta - seedexpander_init(&seedexpander, theta, theta + 32, SEEDEXPANDER_MAX_LENGTH); - - // Retrieve h and s from public key - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_from_string(h, s, pk); - - // Generate r1, r2 and e - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, r1, PARAM_OMEGA_R); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&seedexpander, r2, PARAM_OMEGA_R); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(&seedexpander, e, PARAM_OMEGA_E); - - // Compute u = r1 + r2.h - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(u, r2, h, PARAM_OMEGA_R); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(u, r1, u, VEC_N_SIZE_BYTES); - - // Compute v = m.G by encoding the message - PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_encode(v, m); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - - // Compute v = m.G + s.r2 + e - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(tmp2, r2, s, PARAM_OMEGA_R); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(tmp2, e, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_resize(v, PARAM_N1N2, tmp2, PARAM_N); -} - - - -/** - * @brief Decryption of the HQC_PKE IND_CPA scheme - * - * @param[out] m Vector representing the decrypted message - * @param[in] u Vector u (first part of the ciphertext) - * @param[in] v Vector v (second part of the ciphertext) - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk) { - uint8_t x[VEC_N_SIZE_BYTES] = {0}; - uint32_t y[PARAM_OMEGA] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t tmp1[VEC_N_SIZE_BYTES] = {0}; - uint8_t tmp2[VEC_N_SIZE_BYTES] = {0}; - - // Retrieve x, y, pk from secret key - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_from_string(x, y, pk, sk); - - // Compute v - u.y - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_resize(tmp1, PARAM_N, v, PARAM_N1N2); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_mul(tmp2, y, u, PARAM_OMEGA); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(tmp2, tmp1, tmp2, VEC_N_SIZE_BYTES); - - // Compute m by decoding v - u.y - PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_decode(m, tmp2); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/hqc.h b/crypto_kem/hqc-256-3-cca2/leaktime/hqc.h deleted file mode 100644 index 5cc99e1c..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/hqc.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_HQC_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_HQC_H - -/** - * @file hqc.h - * @brief Functions of the HQC_PKE IND_CPA scheme - */ - -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_keygen(uint8_t *pk, uint8_t *sk); -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_encrypt(uint8_t *u, uint8_t *v, const uint8_t *m, const uint8_t *theta, const uint8_t *pk); -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_decrypt(uint8_t *m, const uint8_t *u, const uint8_t *v, const uint8_t *sk); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/kem.c b/crypto_kem/hqc-256-3-cca2/leaktime/kem.c deleted file mode 100644 index 293c7107..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/kem.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file kem.c - * @brief Implementation of api.h - */ - -#include "api.h" -#include "hqc.h" -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "sha2.h" -#include "vector.h" -#include -#include - - -/** - * @brief Keygen of the HQC_KEM IND_CAA2 scheme - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h. - * - * The secret key is composed of the seed used to generate vectors x and y. - * As a technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] pk String containing the public key - * @param[out] sk String containing the secret key - * @returns 0 if keygen is successful - */ -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_keygen(pk, sk); - return 0; -} - - - -/** - * @brief Encapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ct String containing the ciphertext - * @param[out] ss String containing the shared secret - * @param[in] pk String containing the public key - * @returns 0 if encapsulation is successful - */ -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES]; - uint8_t diversifier_bytes[8] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - - // Computing m - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_from_randombytes(m); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_encrypt(u, v, m, theta, pk); - - // Computing d - sha512(d, m, VEC_K_SIZE_BYTES); - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - // Computing ciphertext - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_to_string(ct, u, v, d); - - return 0; -} - - - -/** - * @brief Decapsulation of the HQC_KEM IND_CAA2 scheme - * - * @param[out] ss String containing the shared secret - * @param[in] ct String containing the cipĥertext - * @param[in] sk String containing the secret key - * @returns 0 if decapsulation is successful, -1 otherwise - */ -int PQCLEAN_HQC2563CCA2_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { - AES_XOF_struct G_seedexpander; - uint8_t seed_G[VEC_K_SIZE_BYTES] = {0}; - uint8_t diversifier_bytes[8] = {0}; - uint8_t u[VEC_N_SIZE_BYTES] = {0}; - uint8_t v[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d[SHA512_BYTES] = {0}; - uint8_t pk[PUBLIC_KEY_BYTES] = {0}; - uint8_t m[VEC_K_SIZE_BYTES] = {0}; - uint8_t theta[SEED_BYTES] = {0}; - uint8_t u2[VEC_N_SIZE_BYTES] = {0}; - uint8_t v2[VEC_N1N2_SIZE_BYTES] = {0}; - uint8_t d2[SHA512_BYTES] = {0}; - uint8_t mc[VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES] = {0}; - int8_t abort = 0; - - // Retrieving u, v and d from ciphertext - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_from_string(u, v, d, ct); - - // Retrieving pk from sk - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); - - // Decryting - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_decrypt(m, u, v, sk); - - // Generating G function - memcpy(seed_G, m, VEC_K_SIZE_BYTES); - seedexpander_init(&G_seedexpander, seed_G, diversifier_bytes, SEEDEXPANDER_MAX_LENGTH); - - // Computing theta - seedexpander(&G_seedexpander, theta, SEED_BYTES); - - // Encrypting m' - PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_pke_encrypt(u2, v2, m, theta, pk); - - // Checking that c = c' and abort otherwise - if (PQCLEAN_HQC2563CCA2_LEAKTIME_vect_compare(u, u2, VEC_N_SIZE_BYTES) != 0 || - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_compare(v, v2, VEC_N1N2_SIZE_BYTES) != 0) { - abort = 1; - } - - // Computing d' - sha512(d2, m, VEC_K_SIZE_BYTES); - - // Checking that d = d' and abort otherwise - if (memcmp(d, d2, SHA512_BYTES) != 0) { - abort = 1; - } - - if (abort == 1) { - memset(ss, 0, SHARED_SECRET_BYTES); - return -1; - } - - // Computing shared secret - memcpy(mc, m, VEC_K_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES, u, VEC_N_SIZE_BYTES); - memcpy(mc + VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - sha512(ss, mc, VEC_K_SIZE_BYTES + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES); - - return 0; -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/parameters.h b/crypto_kem/hqc-256-3-cca2/leaktime/parameters.h deleted file mode 100644 index bc16d522..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/parameters.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_HQC_PARAMETERS_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_HQC_PARAMETERS_H - -/** - * @file parameters.h - * @brief Parameters of the HQC_KEM IND-CCA2 scheme - */ - -#include "api.h" - -#define CEIL_DIVIDE(a, b) (((a)/(b)) + ((a) % (b) == 0 ? 0 : 1)) /*!< Divide a by b and ceil the result*/ -#define BITMASK(a, size) ((1ULL << ((a) % (size))) - 1) /*!< Create a mask*/ - - -/* - #define PARAM_N Define the parameter n of the scheme - #define PARAM_N1 Define the parameter n1 of the scheme (length of BCH code) - #define PARAM_N2 Define the parameter n2 of the scheme (length of the repetition code) - #define PARAM_N1N2 Define the parameter n1 * n2 of the scheme (length of the tensor code) - #define PARAM_OMEGA Define the parameter omega of the scheme - #define PARAM_OMEGA_E Define the parameter omega_e of the scheme - #define PARAM_OMEGA_R Define the parameter omega_r of the scheme - #define PARAM_SECURITY Define the security level corresponding to the chosen parameters - #define PARAM_DFR_EXP Define the decryption failure rate corresponding to the chosen parameters - - #define SECRET_KEY_BYTES Define the size of the secret key in bytes - #define PUBLIC_KEY_BYTES Define the size of the public key in bytes - #define SHARED_SECRET_BYTES Define the size of the shared secret in bytes - #define CIPHERTEXT_BYTES Define the size of the ciphertext in bytes - - #define UTILS_REJECTION_THRESHOLD Define the rejection threshold used to generate given weight vectors (see vector_set_random_fixed_weight function) - #define VEC_N_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N sized vector in bytes - #define VEC_N1_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1 sized vector in bytes - #define VEC_N1N2_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_N1N2 sized vector in bytes - #define VEC_K_ARRAY_SIZE_BYTES Define the size of the array used to store a PARAM_K sized vector in bytes - - #define PARAM_T Define a threshold for decoding repetition code word (PARAM_T = (PARAM_N2 - 1) / 2) - - #define PARAM_DELTA Define the parameter delta of the scheme (correcting capacity of the BCH code) - #define PARAM_M Define a positive integer - #define PARAM_GF_MUL_ORDER Define the size of the multiplicative group of GF(2^m), i.e 2^m -1 - #define PARAM_K Define the size of the information bits of the BCH code - #define PARAM_G Define the size of the generator polynomial of BCH code - #define PARAM_FFT The additive FFT takes a 2^PARAM_FFT polynomial as input - We use the FFT to compute the roots of sigma, whose degree if PARAM_DELTA=60 - The smallest power of 2 greater than 60+1 is 64=2^6 - #define PARAM_FFT_T The additive FFT transpose computes a (2^PARAM_FFT_T)-sized syndrome vector - We want to compute 2*PARAM_DELTA=120 syndromes - The smallest power of 2 greater than 120 is 2^7 - #define PARAM_BCH_POLY Generator polynomial of the BCH code - - #define SHA512_BYTES Define the size of SHA512 output in bytes - #define SEED_BYTES Define the size of the seed in bytes - #define SEEDEXPANDER_MAX_LENGTH Define the seed expander max length -*/ - - -#define PARAM_N 70853 -#define PARAM_N1 796 -#define PARAM_N2 89 -#define PARAM_N1N2 70844 -#define PARAM_OMEGA 133 -#define PARAM_OMEGA_E 153 -#define PARAM_OMEGA_R 153 -#define PARAM_SECURITY 256 -#define PARAM_DFR_EXP 256 - -#define SECRET_KEY_BYTES PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_SECRETKEYBYTES -#define PUBLIC_KEY_BYTES PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_PUBLICKEYBYTES -#define SHARED_SECRET_BYTES PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_BYTES -#define CIPHERTEXT_BYTES PQCLEAN_HQC2563CCA2_LEAKTIME_CRYPTO_CIPHERTEXTBYTES - -#define UTILS_REJECTION_THRESHOLD 16721308 -#define VEC_K_SIZE_BYTES CEIL_DIVIDE(PARAM_K, 8) -#define VEC_N_SIZE_BYTES CEIL_DIVIDE(PARAM_N, 8) -#define VEC_N1_SIZE_BYTES CEIL_DIVIDE(PARAM_N1, 8) -#define VEC_N1N2_SIZE_BYTES CEIL_DIVIDE(PARAM_N1N2, 8) - -#define PARAM_T 44 - -#define PARAM_DELTA 60 -#define PARAM_M 10 -#define PARAM_GF_MUL_ORDER 1023 -#define PARAM_K 256 -#define PARAM_G 541 -#define PARAM_FFT 6 -#define PARAM_FFT_T 7 -#define PARAM_BCH_POLY { \ - 1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,0, \ - 1,0,0,1,0,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,0,1,0,1,0,1,1,0,0, \ - 1,0,1,0,0,1,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,1,0, \ - 0,1,0,1,1,1,0,0,0,1,1,1,1,0,0,0,1,0,1,1,1,1,0,1,0,0,1,1,1,1,0,1, \ - 0,0,0,1,0,0,1,1,1,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,0,1,0,0,1,0,0,0, \ - 1,1,0,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,1,0,1,0,0,1,0,0,1,1,0,1,0, \ - 0,0,0,1,1,0,0,0,0,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1, \ - 1,0,1,1,0,0,0,1,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,1,0, \ - 0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,1,1,0,0,1,0,1,1, \ - 1,1,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,0,0,0,0,1,0,1,1,1,0,1,0,1, \ - 0,0,0,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,0,1,1,0,0,0, \ - 1,0,0,1,0,0,1,1,0,0,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,0,1,0,1,1, \ - 0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,1,1,1, \ - 0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,1,0,1,1,1,1,1,0,0,1,0,0,1,1,0,0, \ - 0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,1,0,0,0,0,1,0,1,1, \ - 1,1,0,0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,0,1,0,0, \ - 1,0,1,1,0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1 \ - }; - -#define SHA512_BYTES 64 -#define SEED_BYTES 40 -#define SEEDEXPANDER_MAX_LENGTH 4294967295 - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/parsing.c b/crypto_kem/hqc-256-3-cca2/leaktime/parsing.c deleted file mode 100644 index 6c1fbc19..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/parsing.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file parsing.c - * @brief Functions to parse secret key, public key and ciphertext of the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "parsing.h" -#include "vector.h" -#include -#include - - -/** - * @brief Parse a secret key into a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] sk String containing the secret key - * @param[in] sk_seed Seed used to generate the secret key - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk) { - memcpy(sk, sk_seed, SEED_BYTES); - memcpy(sk + SEED_BYTES, pk, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a secret key from a string - * - * The secret key is composed of the seed used to generate vectors x and y. - * As technicality, the public key is appended to the secret key in order to respect NIST API. - * - * @param[out] x uint8_t representation of vector x - * @param[out] y uint8_t representation of vector y - * @param[out] pk String containing the public key - * @param[in] sk String containing the secret key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk) { - AES_XOF_struct sk_seedexpander; - uint8_t sk_seed[SEED_BYTES] = {0}; - - memcpy(sk_seed, sk, SEED_BYTES); - seedexpander_init(&sk_seedexpander, sk_seed, sk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(&sk_seedexpander, x, PARAM_OMEGA); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(&sk_seedexpander, y, PARAM_OMEGA); - memcpy(pk, sk + SEED_BYTES, PUBLIC_KEY_BYTES); -} - - - -/** - * @brief Parse a public key into a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] pk String containing the public key - * @param[in] pk_seed Seed used to generate the public key - * @param[in] s uint8_t representation of vector s - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s) { - memcpy(pk, pk_seed, SEED_BYTES); - memcpy(pk + SEED_BYTES, s, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a public key from a string - * - * The public key is composed of the syndrome s as well as the seed used to generate the vector h - * - * @param[out] h uint8_t representation of vector h - * @param[out] s uint8_t representation of vector s - * @param[in] pk String containing the public key - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk) { - AES_XOF_struct pk_seedexpander; - uint8_t pk_seed[SEED_BYTES] = {0}; - - memcpy(pk_seed, pk, SEED_BYTES); - seedexpander_init(&pk_seedexpander, pk_seed, pk_seed + 32, SEEDEXPANDER_MAX_LENGTH); - PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random(&pk_seedexpander, h); - - memcpy(s, pk + SEED_BYTES, VEC_N_SIZE_BYTES); -} - - - -/** - * @brief Parse a ciphertext into a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] ct String containing the ciphertext - * @param[in] u uint8_t representation of vector u - * @param[in] v uint8_t representation of vector v - * @param[in] d String containing the hash d - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d) { - memcpy(ct, u, VEC_N_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES, v, VEC_N1N2_SIZE_BYTES); - memcpy(ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, d, SHA512_BYTES); -} - - - -/** - * @brief Parse a ciphertext from a string - * - * The ciphertext is composed of vectors u, v and hash d. - * - * @param[out] u uint8_t representation of vector u - * @param[out] v uint8_t representation of vector v - * @param[out] d String containing the hash d - * @param[in] ct String containing the ciphertext - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct) { - memcpy(u, ct, VEC_N_SIZE_BYTES); - memcpy(v, ct + VEC_N_SIZE_BYTES, VEC_N1N2_SIZE_BYTES); - memcpy(d, ct + VEC_N_SIZE_BYTES + VEC_N1N2_SIZE_BYTES, SHA512_BYTES); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/parsing.h b/crypto_kem/hqc-256-3-cca2/leaktime/parsing.h deleted file mode 100644 index 56c01d35..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/parsing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_PARSING_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_PARSING_H - -/** - * @file parsing.h - * @brief Header file for parsing.c - */ - -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_to_string(uint8_t *sk, const uint8_t *sk_seed, const uint8_t *pk); -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_secret_key_from_string(uint8_t *x, uint32_t *y, uint8_t *pk, const uint8_t *sk); - -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_to_string(uint8_t *pk, const uint8_t *pk_seed, const uint8_t *s); -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_public_key_from_string(uint8_t *h, uint8_t *s, const uint8_t *pk); - -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_to_string(uint8_t *ct, const uint8_t *u, const uint8_t *v, const uint8_t *d); -void PQCLEAN_HQC2563CCA2_LEAKTIME_hqc_ciphertext_from_string(uint8_t *u, uint8_t *v, uint8_t *d, const uint8_t *ct); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/repetition.c b/crypto_kem/hqc-256-3-cca2/leaktime/repetition.c deleted file mode 100644 index 892dbbb0..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/repetition.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file repetition.c - * @brief Implementation of repetition codes - */ - -#include "parameters.h" -#include "repetition.h" -#include -#include - -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v); - - -/** - * @brief Encoding each bit in the message m using the repetition code - * - * For reasons of clarity and comprehensibility, we do the encoding by storing the encoded bits in a String (each bit in an a uint8_t), - * then we parse the obtained string to an compact array using the function array_to_rep_codeword(). - * - * @param[out] em Pointer to an array that is the code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[PARAM_N1N2] = {0}; - uint8_t bit = 0; - uint32_t index; - - for (size_t i = 0; i < (VEC_N1_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - bit = (m[i] >> j) & 0x01; - index = (8 * (uint32_t)i + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - } - - for (uint8_t j = 0; j < (PARAM_N1 % 8); ++j) { - bit = (m[VEC_N1_SIZE_BYTES - 1] >> j) & 0x01; - index = (8 * (VEC_N1_SIZE_BYTES - 1) + j) * PARAM_N2; - for (uint8_t k = 0; k < PARAM_N2; ++k) { - tmp[index + k] = bit; - } - } - - array_to_rep_codeword(em, tmp); -} - - - -/** - * @brief Decoding the code words to a message using the repetition code - * - * We use a majority decoding. In fact we have that PARAM_N2 = 2 * PARAM_T + 1, thus, - * if the Hamming weight of the vector is greater than PARAM_T, the code word is decoded - * to 1 and 0 otherwise. - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em) { - size_t t = 0; // m index - uint8_t k = PARAM_N2; // block counter - uint8_t ones = 0; // number of 1 in the current block - - for (size_t i = 0; i < VEC_N1N2_SIZE_BYTES; ++i) { - for (uint8_t j = 0; j < 8; ++j) { - ones += (em[i] >> j) & 0x01; - - if (--k) { - continue; - } - - m[t / 8] |= (ones > PARAM_T) << t % 8; - ++t; - k = PARAM_N2; - ones = 0; - } - } -} - - - -/** - * @brief Parse an array to an compact array - * - * @param[out] o Pointer to an array - * @param[in] v Pointer to an array - */ -static void array_to_rep_codeword(uint8_t *o, const uint8_t *v) { - for (size_t i = 0; i < (VEC_N1N2_SIZE_BYTES - 1); ++i) { - for (uint8_t j = 0; j < 8; ++j) { - o[i] |= v[j + 8 * i] << j; - } - } - - for (uint8_t j = 0; j < PARAM_N1N2 % 8; ++j) { - o[VEC_N1N2_SIZE_BYTES - 1] |= (v[j + 8 * (VEC_N1N2_SIZE_BYTES - 1)]) << j; - } -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/repetition.h b/crypto_kem/hqc-256-3-cca2/leaktime/repetition.h deleted file mode 100644 index 3a47212a..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/repetition.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_REPETITION_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_REPETITION_H - -/** - * @file repetition.h - * @brief Header file for repetition.c - */ - -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/tensor.c b/crypto_kem/hqc-256-3-cca2/leaktime/tensor.c deleted file mode 100644 index 4ebfb8e6..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/tensor.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file tensor.c - * @brief Implementation of tensor code - */ - -#include "bch.h" -#include "parameters.h" -#include "repetition.h" -#include "tensor.h" -#include - - -/** - * @brief Encoding the message m to a code word em using the tensor code - * - * First we encode the message using the BCH code, then with the repetition code to obtain - * a tensor code word. - * - * @param[out] em Pointer to an array that is the tensor code word - * @param[in] m Pointer to an array that is the message - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_encode(tmp, m); - PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_encode(em, tmp); -} - - - -/** - * @brief Decoding the code word em to a message m using the tensor code - * - * @param[out] m Pointer to an array that is the message - * @param[in] em Pointer to an array that is the code word - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em) { - uint8_t tmp[VEC_N1_SIZE_BYTES] = {0}; - - PQCLEAN_HQC2563CCA2_LEAKTIME_repetition_code_decode(tmp, em); - PQCLEAN_HQC2563CCA2_LEAKTIME_bch_code_decode(m, tmp); -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/tensor.h b/crypto_kem/hqc-256-3-cca2/leaktime/tensor.h deleted file mode 100644 index 9afcf9e0..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/tensor.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_TENSOR_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_TENSOR_H - -/** - * @file tensor.h - * @brief Header file for tensor.c - */ - -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_encode(uint8_t *em, const uint8_t *m); -void PQCLEAN_HQC2563CCA2_LEAKTIME_tensor_code_decode(uint8_t *m, const uint8_t *em); - -#endif diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/util.c b/crypto_kem/hqc-256-3-cca2/leaktime/util.c deleted file mode 100644 index 5471f9ab..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/util.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "util.h" -#include "stddef.h" - -#include "assert.h" - -/* These functions should help with endianness-safe conversions - * - * load8 and store8 are copied from the McEliece implementations, - * which are in the public domain. - */ - - -void PQCLEAN_HQC2563CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in) { - out[0] = (in >> 0x00) & 0xFF; - out[1] = (in >> 0x08) & 0xFF; - out[2] = (in >> 0x10) & 0xFF; - out[3] = (in >> 0x18) & 0xFF; - out[4] = (in >> 0x20) & 0xFF; - out[5] = (in >> 0x28) & 0xFF; - out[6] = (in >> 0x30) & 0xFF; - out[7] = (in >> 0x38) & 0xFF; -} - - -uint64_t PQCLEAN_HQC2563CCA2_LEAKTIME_load8(const unsigned char *in) { - uint64_t ret = in[7]; - - for (int8_t i = 6; i >= 0; i--) { - ret <<= 8; - ret |= in[i]; - } - - return ret; -} - -void PQCLEAN_HQC2563CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen) { - size_t index_in = 0; - size_t index_out = 0; - - // first copy by 8 bytes - if (inlen >= 8 && outlen >= 1) { - while (index_out < outlen && index_in + 8 <= inlen) { - out64[index_out] = PQCLEAN_HQC2563CCA2_LEAKTIME_load8(in8 + index_in); - - index_in += 8; - index_out += 1; - } - } - - // we now need to do the last 7 bytes if necessary - if (index_in >= inlen || index_out >= outlen) { - return; - } - out64[index_out] = in8[inlen - 1]; - for (int8_t i = (int8_t)(inlen - index_in) - 2; i >= 0; i--) { - out64[index_out] <<= 8; - out64[index_out] |= in8[index_in + i]; - } -} - -void PQCLEAN_HQC2563CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen) { - for (size_t index_out = 0, index_in = 0; index_out < outlen && index_in < inlen;) { - out8[index_out] = (in64[index_in] >> ((index_out % 8) * 8)) & 0xFF; - index_out++; - if (index_out % 8 == 0) { - index_in++; - } - } -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/util.h b/crypto_kem/hqc-256-3-cca2/leaktime/util.h deleted file mode 100644 index daada400..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/util.h +++ /dev/null @@ -1,9 +0,0 @@ -/* These functions should help with endianness-safe conversions */ - -#include -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_store8(unsigned char *out, uint64_t in); -uint64_t PQCLEAN_HQC2563CCA2_LEAKTIME_load8(const unsigned char *in); -void PQCLEAN_HQC2563CCA2_LEAKTIME_load8_arr(uint64_t *out64, size_t outlen, const uint8_t *in8, size_t inlen); -void PQCLEAN_HQC2563CCA2_LEAKTIME_store8_arr(uint8_t *out8, size_t outlen, const uint64_t *in64, size_t inlen); diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/vector.c b/crypto_kem/hqc-256-3-cca2/leaktime/vector.c deleted file mode 100644 index 3c0117f7..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/vector.c +++ /dev/null @@ -1,224 +0,0 @@ -/** - * @file vector.c - * @brief Implementation of vectors sampling and some utilities for the HQC scheme - */ - -#include "nistseedexpander.h" -#include "parameters.h" -#include "randombytes.h" -#include "vector.h" -#include -#include - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. The vector - * is stored by position. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight) { - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (v[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - v[i] = random_data; - } - } -} - - - -/** - * @brief Generates a vector of a given Hamming weight - * - * This function generates uniformly at random a binary vector of a Hamming weight equal to the parameter weight. - * To generate the vector we have to sample uniformly at random values in the interval [0, PARAM_N -1]. Suppose the PARAM_N is equal to \f$ 70853 \f$, to select a position \f$ r\f$ the function works as follow: - * 1. It makes a call to the seedexpander function to obtain a random number \f$ x\f$ in \f$ [0, 2^{24}[ \f$. - * 2. Let \f$ t = \lfloor {2^{24} \over 70853} \rfloor \times 70853\f$ - * 3. If \f$ x \geq t\f$, go to 1 - * 4. It return \f$ r = x \mod 70853\f$ - * - * The parameter \f$ t \f$ is precomputed and it's denoted by UTILS_REJECTION_THRESHOLD (see the file parameters.h). - * - * @param[in] v Pointer to an array - * @param[in] weight Integer that is the Hamming weight - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight) { - - size_t random_bytes_size = 3 * weight; - uint8_t rand_bytes[3 * PARAM_OMEGA_R] = {0}; // weight is expected to be <= PARAM_OMEGA_R - uint32_t random_data = 0; - uint32_t tmp[PARAM_OMEGA_R] = {0}; - uint8_t exist = 0; - size_t j = 0; - - seedexpander(ctx, rand_bytes, random_bytes_size); - - for (uint32_t i = 0; i < weight; ++i) { - exist = 0; - do { - if (j == random_bytes_size) { - seedexpander(ctx, rand_bytes, random_bytes_size); - j = 0; - } - - random_data = ((uint32_t) rand_bytes[j++]) << 16; - random_data |= ((uint32_t) rand_bytes[j++]) << 8; - random_data |= rand_bytes[j++]; - - } while (random_data >= UTILS_REJECTION_THRESHOLD); - - random_data = random_data % PARAM_N; - - for (uint32_t k = 0; k < i; k++) { - if (tmp[k] == random_data) { - exist = 1; - } - } - - if (exist == 1) { - i--; - } else { - tmp[i] = random_data; - } - } - - for (uint16_t i = 0; i < weight; ++i) { - int32_t index = tmp[i] / 8; - int32_t pos = tmp[i] % 8; - v[index] |= 1 << pos; - } -} - - - -/** - * @brief Generates a random vector of dimension PARAM_N - * - * This function generates a random binary vector of dimension PARAM_N. It generates a random - * array of bytes using the seedexpander function, and drop the extra bits using a mask. - * - * @param[in] v Pointer to an array - * @param[in] ctx Pointer to the context of the seed expander - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v) { - uint8_t rand_bytes[VEC_N_SIZE_BYTES] = {0}; - - seedexpander(ctx, rand_bytes, VEC_N_SIZE_BYTES); - - memcpy(v, rand_bytes, VEC_N_SIZE_BYTES); - v[VEC_N_SIZE_BYTES - 1] &= BITMASK(PARAM_N, 8); -} - - - -/** - * @brief Generates a random vector - * - * This function generates a random binary vector. It uses the the randombytes function. - * - * @param[in] v Pointer to an array - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v) { - uint8_t rand_bytes [VEC_K_SIZE_BYTES] = {0}; - - randombytes(rand_bytes, VEC_K_SIZE_BYTES); - memcpy(v, rand_bytes, VEC_K_SIZE_BYTES); -} - - - -/** - * @brief Adds two vectors - * - * @param[out] o Pointer to an array that is the result - * @param[in] v1 Pointer to an array that is the first vector - * @param[in] v2 Pointer to an array that is the second vector - * @param[in] size Integer that is the size of the vectors - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size) { - for (uint32_t i = 0; i < size; ++i) { - o[i] = v1[i] ^ v2[i]; - } -} - - - -/** - * @brief Compares two vectors - * - * @param[in] v1 Pointer to an array that is first vector - * @param[in] v2 Pointer to an array that is second vector - * @param[in] size Integer that is the size of the vectors - * @returns 0 if the vectors are equals and a negative/psotive value otherwise - */ -int PQCLEAN_HQC2563CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size) { - return memcmp(v1, v2, size); -} - - - -/** - * @brief Resize a vector so that it contains size_o bits - * - * @param[out] o Pointer to the output vector - * @param[in] size_o Integer that is the size of the output vector in bits - * @param[in] v Pointer to the input vector - * @param[in] size_v Integer that is the size of the input vector in bits - */ -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v) { - if (size_o < size_v) { - uint8_t mask = 0x7F; - int8_t val = 8 - (size_o % 8); - - memcpy(o, v, VEC_N1N2_SIZE_BYTES); - - for (int8_t i = 0; i < val; ++i) { - o[VEC_N1N2_SIZE_BYTES - 1] &= (mask >> i); - } - } else { - memcpy(o, v, CEIL_DIVIDE(size_v, 8)); - } -} diff --git a/crypto_kem/hqc-256-3-cca2/leaktime/vector.h b/crypto_kem/hqc-256-3-cca2/leaktime/vector.h deleted file mode 100644 index 5034c987..00000000 --- a/crypto_kem/hqc-256-3-cca2/leaktime/vector.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef PQCLEAN_HQC2563CCA2_LEAKTIME_VECTOR_H -#define PQCLEAN_HQC2563CCA2_LEAKTIME_VECTOR_H - -/** - * @file vector.h - * @brief Header file for vector.c - */ - -#include "nistseedexpander.h" -#include - -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight_by_coordinates(AES_XOF_struct *ctx, uint32_t *v, uint16_t weight); -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_fixed_weight(AES_XOF_struct *ctx, uint8_t *v, uint16_t weight); -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random(AES_XOF_struct *ctx, uint8_t *v); -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_set_random_from_randombytes(uint8_t *v); - -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_add(uint8_t *o, const uint8_t *v1, const uint8_t *v2, uint32_t size); -int PQCLEAN_HQC2563CCA2_LEAKTIME_vect_compare(const uint8_t *v1, const uint8_t *v2, uint32_t size); - -void PQCLEAN_HQC2563CCA2_LEAKTIME_vect_resize(uint8_t *o, uint32_t size_o, const uint8_t *v, uint32_t size_v); - -#endif