Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ML-DSA-ipd and ML-KEM-ipd & NIST supplied test vectors #1626

Merged
merged 27 commits into from
Feb 19, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Pulls ML-DSA-ipd
Adds test cases with NIST supplied test vectors for ML-DSA/ML-KEM
  • Loading branch information
bhess committed Feb 19, 2024
commit a90b1de832124af3bf4260af4a53aa778598de4a
25 changes: 24 additions & 1 deletion .CMake/alg_support.cmake
Original file line number Diff line number Diff line change
@@ -273,6 +273,29 @@ endif()
endif()


option(OQS_ENABLE_SIG_ML_DSA "Enable ml_dsa algorithm family" ON)
cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_44 "" ON "OQS_ENABLE_SIG_ML_DSA" OFF)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux")
if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS AND OQS_USE_POPCNT_INSTRUCTIONS))
cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_44_avx2 "" ON "OQS_ENABLE_SIG_ml_dsa_44" OFF)
endif()
endif()

cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_65 "" ON "OQS_ENABLE_SIG_ML_DSA" OFF)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux")
if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS AND OQS_USE_POPCNT_INSTRUCTIONS))
cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_65_avx2 "" ON "OQS_ENABLE_SIG_ml_dsa_65" OFF)
endif()
endif()

cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_87 "" ON "OQS_ENABLE_SIG_ML_DSA" OFF)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux")
if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS AND OQS_USE_POPCNT_INSTRUCTIONS))
cmake_dependent_option(OQS_ENABLE_SIG_ml_dsa_87_avx2 "" ON "OQS_ENABLE_SIG_ml_dsa_87" OFF)
endif()
endif()


option(OQS_ENABLE_SIG_FALCON "Enable falcon algorithm family" ON)
cmake_dependent_option(OQS_ENABLE_SIG_falcon_512 "" ON "OQS_ENABLE_SIG_FALCON" OFF)
if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS))
@@ -396,7 +419,7 @@ if(NOT ((OQS_MINIMAL_BUILD STREQUAL "") OR (OQS_MINIMAL_BUILD STREQUAL "OFF")))
filter_algs("${OQS_MINIMAL_BUILD}")
elseif (${OQS_ALGS_ENABLED} STREQUAL "STD")
##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_START
filter_algs("KEM_kyber_512;KEM_kyber_768;KEM_kyber_1024;SIG_dilithium_2;SIG_dilithium_3;SIG_dilithium_5;SIG_falcon_512;SIG_falcon_1024;SIG_sphincs_sha2_128f_simple;SIG_sphincs_sha2_128s_simple;SIG_sphincs_sha2_192f_simple;SIG_sphincs_sha2_192s_simple;SIG_sphincs_sha2_256f_simple;SIG_sphincs_sha2_256s_simple;SIG_sphincs_shake_128f_simple;SIG_sphincs_shake_128s_simple;SIG_sphincs_shake_192f_simple;SIG_sphincs_shake_192s_simple;SIG_sphincs_shake_256f_simple;SIG_sphincs_shake_256s_simple")
filter_algs("KEM_kyber_512;KEM_kyber_768;KEM_kyber_1024;SIG_dilithium_2;SIG_dilithium_3;SIG_dilithium_5;SIG_ml_dsa_44;SIG_ml_dsa_65;SIG_ml_dsa_87;SIG_falcon_512;SIG_falcon_1024;SIG_sphincs_sha2_128f_simple;SIG_sphincs_sha2_128s_simple;SIG_sphincs_sha2_192f_simple;SIG_sphincs_sha2_192s_simple;SIG_sphincs_sha2_256f_simple;SIG_sphincs_sha2_256s_simple;SIG_sphincs_shake_128f_simple;SIG_sphincs_shake_128s_simple;SIG_sphincs_shake_192f_simple;SIG_sphincs_shake_192s_simple;SIG_sphincs_shake_256f_simple;SIG_sphincs_shake_256s_simple")
##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_END
elseif(${OQS_ALGS_ENABLED} STREQUAL "NIST_R4")
filter_algs("KEM_classic_mceliece_348864;KEM_classic_mceliece_348864f;KEM_classic_mceliece_460896;KEM_classic_mceliece_460896f;KEM_classic_mceliece_6688128;KEM_classic_mceliece_6688128f;KEM_classic_mceliece_6960119;KEM_classic_mceliece_6960119f;KEM_classic_mceliece_8192128;KEM_classic_mceliece_8192128f;KEM_hqc_128;KEM_hqc_192;KEM_hqc_256;KEM_bike_l1;KEM_bike_l3")
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -170,6 +170,9 @@ endif()
if(OQS_ENABLE_SIG_DILITHIUM)
set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/dilithium/sig_dilithium.h)
endif()
if(OQS_ENABLE_SIG_ML_DSA)
set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/ml_dsa/sig_ml_dsa.h)
endif()
if(OQS_ENABLE_SIG_FALCON)
set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/falcon/sig_falcon.h)
endif()
45 changes: 45 additions & 0 deletions scripts/copy_from_upstream/copy_from_upstream.yml
Original file line number Diff line number Diff line change
@@ -37,6 +37,14 @@ upstreams:
sig_meta_path: '{pretty_name_full}_META.yml'
sig_scheme_path: '.'
patches: [pqcrystals-dilithium-yml.patch, pqcrystals-dilithium-ref-shake-aes.patch, pqcrystals-dilithium-avx2-shake-aes.patch]
-
name: pqcrystals-dilithium-standard
git_url: https://github.com/bhess/dilithium.git
git_branch: bhe-standard-fixes
git_commit: 588562ac2cc777dfa407e34532d945b5f06b8ffd
sig_meta_path: '{pretty_name_full}_META.yml'
sig_scheme_path: '.'
patches: [pqcrystals-dilithium-standard-yml.patch, pqcrystals-dilithium-standard-ref-shake-aes.patch, pqcrystals-dilithium-standard-avx2-shake-aes.patch]
kems:
-
name: classic_mceliece
@@ -121,6 +129,23 @@ kems:
scheme: "1024"
pqclean_scheme: kyber1024
pretty_name_full: Kyber1024
# -
# name: ml-kem
# default_implementation: ref
# upstream_location: pqcrystals-kyber-standard
# schemes:
# -
# scheme: "512"
# pqclean_scheme: ml-kem-512-ipd
# pretty_name_full: ML-KEM-512-ipd
# -
# scheme: "768"
# pqclean_scheme: ml-kem-768-ipd
# pretty_name_full: ML-KEM-768-ipd
# -
# scheme: "1024"
# pqclean_scheme: ml-kem-1024-ipd
# pretty_name_full: ML-KEM-512-ipd
sigs:
-
name: dilithium
@@ -146,6 +171,26 @@ sigs:
pqclean_scheme: dilithium5
pretty_name_full: Dilithium5
signed_msg_order: sig_then_msg
-
name: ml_dsa
default_implementation: ref
upstream_location: pqcrystals-dilithium-standard
schemes:
-
scheme: "44"
pqclean_scheme: ml-dsa-44-ipd
pretty_name_full: ML-DSA-44-ipd
signed_msg_order: sig_then_msg
-
scheme: "65"
pqclean_scheme: ml-dsa-65-ipd
pretty_name_full: ML-DSA-65-ipd
signed_msg_order: sig_then_msg
-
scheme: "87"
pqclean_scheme: ml-dsa-87-ipd
pretty_name_full: ML-DSA-87-ipd
signed_msg_order: sig_then_msg
-
name: falcon
default_implementation: clean
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
diff --git a/avx2/poly.c b/avx2/poly.c
index c1b21c1..25d3682 100644
--- a/avx2/poly.c
+++ b/avx2/poly.c
@@ -401,6 +401,7 @@ void poly_uniform(poly *a, const uint8_t seed[SEEDBYTES], uint16_t nonce)
stream128_state state;
stream128_init(&state, seed, nonce);
poly_uniform_preinit(a, &state);
+ stream128_release(&state);
}

void poly_uniform_4x(poly *a0,
@@ -415,7 +416,7 @@ void poly_uniform_4x(poly *a0,
{
unsigned int ctr0, ctr1, ctr2, ctr3;
ALIGNED_UINT8(REJ_UNIFORM_BUFLEN+8) buf[4];
- keccakx4_state state;
+ shake128x4incctx state;
__m256i f;

f = _mm256_loadu_si256((__m256i *)seed);
@@ -433,6 +434,7 @@ void poly_uniform_4x(poly *a0,
buf[3].coeffs[SEEDBYTES+0] = nonce3;
buf[3].coeffs[SEEDBYTES+1] = nonce3 >> 8;

+ shake128x4_inc_init(&state);
shake128x4_absorb_once(&state, buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, SEEDBYTES + 2);
shake128x4_squeezeblocks(buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, REJ_UNIFORM_NBLOCKS, &state);

@@ -449,6 +451,7 @@ void poly_uniform_4x(poly *a0,
ctr2 += rej_uniform(a2->coeffs + ctr2, N - ctr2, buf[2].coeffs, SHAKE128_RATE);
ctr3 += rej_uniform(a3->coeffs + ctr3, N - ctr3, buf[3].coeffs, SHAKE128_RATE);
}
+ shake128x4_inc_ctx_release(&state);
}

/*************************************************
@@ -530,6 +533,7 @@ void poly_uniform_eta(poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce)
stream256_state state;
stream256_init(&state, seed, nonce);
poly_uniform_eta_preinit(a, &state);
+ stream256_release(&state);
}

void poly_uniform_eta_4x(poly *a0,
@@ -546,7 +550,7 @@ void poly_uniform_eta_4x(poly *a0,
ALIGNED_UINT8(REJ_UNIFORM_ETA_BUFLEN) buf[4];

__m256i f;
- keccakx4_state state;
+ shake256x4incctx state;

f = _mm256_loadu_si256((__m256i *)&seed[0]);
_mm256_store_si256(&buf[0].vec[0],f);
@@ -568,6 +572,7 @@ void poly_uniform_eta_4x(poly *a0,
buf[3].coeffs[64] = nonce3;
buf[3].coeffs[65] = nonce3 >> 8;

+ shake256x4_inc_init(&state);
shake256x4_absorb_once(&state, buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, 66);
shake256x4_squeezeblocks(buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, REJ_UNIFORM_ETA_NBLOCKS, &state);

@@ -584,6 +589,7 @@ void poly_uniform_eta_4x(poly *a0,
ctr2 += rej_eta(a2->coeffs + ctr2, N - ctr2, buf[2].coeffs, SHAKE256_RATE);
ctr3 += rej_eta(a3->coeffs + ctr3, N - ctr3, buf[3].coeffs, SHAKE256_RATE);
}
+ shake256x4_inc_ctx_release(&state);
}

/*************************************************
@@ -611,6 +617,7 @@ void poly_uniform_gamma1(poly *a, const uint8_t seed[CRHBYTES], uint16_t nonce)
stream256_state state;
stream256_init(&state, seed, nonce);
poly_uniform_gamma1_preinit(a, &state);
+ stream256_release(&state);
}

void poly_uniform_gamma1_4x(poly *a0,
@@ -624,7 +631,7 @@ void poly_uniform_gamma1_4x(poly *a0,
uint16_t nonce3)
{
ALIGNED_UINT8(POLY_UNIFORM_GAMMA1_NBLOCKS*STREAM256_BLOCKBYTES+14) buf[4];
- keccakx4_state state;
+ shake256x4incctx state;
__m256i f;

f = _mm256_loadu_si256((__m256i *)&seed[0]);
@@ -647,8 +654,10 @@ void poly_uniform_gamma1_4x(poly *a0,
buf[3].coeffs[64] = nonce3;
buf[3].coeffs[65] = nonce3 >> 8;

+ shake256x4_inc_init(&state);
shake256x4_absorb_once(&state, buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, 66);
shake256x4_squeezeblocks(buf[0].coeffs, buf[1].coeffs, buf[2].coeffs, buf[3].coeffs, POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
+ shake256x4_inc_ctx_release(&state);

polyz_unpack(a0, buf[0].coeffs);
polyz_unpack(a1, buf[1].coeffs);
@@ -670,12 +679,12 @@ void poly_challenge(poly * restrict c, const uint8_t seed[SEEDBYTES]) {
unsigned int i, b, pos;
uint64_t signs;
ALIGNED_UINT8(SHAKE256_RATE) buf;
- keccak_state state;
+ shake256incctx state;

- shake256_init(&state);
- shake256_absorb(&state, seed, SEEDBYTES);
- shake256_finalize(&state);
- shake256_squeezeblocks(buf.coeffs, 1, &state);
+ shake256_inc_init(&state);
+ shake256_inc_absorb(&state, seed, SEEDBYTES);
+ shake256_inc_finalize(&state);
+ shake256_inc_squeeze(buf.coeffs, SHAKE256_RATE, &state);

memcpy(&signs, buf.coeffs, 8);
pos = 8;
@@ -695,6 +704,7 @@ void poly_challenge(poly * restrict c, const uint8_t seed[SEEDBYTES]) {
c->coeffs[b] = 1 - 2*(signs & 1);
signs >>= 1;
}
+ shake256_inc_ctx_release(&state);
}

/*************************************************
diff --git a/avx2/sign.c b/avx2/sign.c
index c8f2398..70599a3 100644
--- a/avx2/sign.c
+++ b/avx2/sign.c
@@ -161,7 +161,7 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t
polyvecl y;
polyveck w0;
} tmpv;
- keccak_state state;
+ shake256incctx state;

rho = seedbuf;
tr = rho + SEEDBYTES;
@@ -172,11 +172,11 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t
unpack_sk(rho, tr, key, &t0, &s1, &s2, sk);

/* Compute CRH(tr, msg) */
- shake256_init(&state);
- shake256_absorb(&state, tr, TRBYTES);
- shake256_absorb(&state, m, mlen);
- shake256_finalize(&state);
- shake256_squeeze(mu, CRHBYTES, &state);
+ shake256_inc_init(&state);
+ shake256_inc_absorb(&state, tr, TRBYTES);
+ shake256_inc_absorb(&state, m, mlen);
+ shake256_inc_finalize(&state);
+ shake256_inc_squeeze(mu, CRHBYTES, &state);

#ifdef DILITHIUM_RANDOMIZED_SIGNING
randombytes(rnd, RNDBYTES);
@@ -223,11 +223,11 @@ rej:
polyveck_decompose(&w1, &tmpv.w0, &w1);
polyveck_pack_w1(sig, &w1);

- shake256_init(&state);
- shake256_absorb(&state, mu, CRHBYTES);
- shake256_absorb(&state, sig, K*POLYW1_PACKEDBYTES);
- shake256_finalize(&state);
- shake256_squeeze(sig, CTILDEBYTES, &state);
+ shake256_inc_ctx_reset(&state);
+ shake256_inc_absorb(&state, mu, CRHBYTES);
+ shake256_inc_absorb(&state, sig, K*POLYW1_PACKEDBYTES);
+ shake256_inc_finalize(&state);
+ shake256_inc_squeeze(sig, CTILDEBYTES, &state);
poly_challenge(&c, sig);
poly_ntt(&c);

@@ -272,6 +272,7 @@ rej:
hint[OMEGA + i] = pos = pos + n;
}

+ shake256_inc_ctx_release(&state);
/* Pack z into signature */
for(i = 0; i < L; i++)
polyz_pack(sig + CTILDEBYTES + i*POLYZ_PACKEDBYTES, &z.vec[i]);
@@ -329,18 +330,19 @@ int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size
polyvecl *row = rowbuf;
polyvecl z;
poly c, w1, h;
- keccak_state state;
+ shake256incctx state;

if(siglen != CRYPTO_BYTES)
return -1;

/* Compute CRH(H(rho, t1), msg) */
shake256(mu, CRHBYTES, pk, CRYPTO_PUBLICKEYBYTES);
- shake256_init(&state);
- shake256_absorb(&state, mu, CRHBYTES);
- shake256_absorb(&state, m, mlen);
- shake256_finalize(&state);
- shake256_squeeze(mu, CRHBYTES, &state);
+ shake256_inc_init(&state);
+ shake256_inc_absorb(&state, mu, CRHBYTES);
+ shake256_inc_absorb(&state, m, mlen);
+ shake256_inc_finalize(&state);
+ shake256_inc_squeeze(mu, CRHBYTES, &state);
+ shake256_inc_ctx_release(&state);

/* Expand challenge */
poly_challenge(&c, sig);
@@ -390,11 +392,12 @@ int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size
if(hint[j]) return -1;

/* Call random oracle and verify challenge */
- shake256_init(&state);
- shake256_absorb(&state, mu, CRHBYTES);
- shake256_absorb(&state, buf.coeffs, K*POLYW1_PACKEDBYTES);
- shake256_finalize(&state);
- shake256_squeeze(buf.coeffs, CTILDEBYTES, &state);
+ shake256_inc_init(&state);
+ shake256_inc_absorb(&state, mu, CRHBYTES);
+ shake256_inc_absorb(&state, buf.coeffs, K*POLYW1_PACKEDBYTES);
+ shake256_inc_finalize(&state);
+ shake256_inc_squeeze(buf.coeffs, CTILDEBYTES, &state);
+ shake256_inc_ctx_release(&state);
for(i = 0; i < CTILDEBYTES; ++i)
if(buf.coeffs[i] != sig[i])
return -1;
diff --git a/avx2/symmetric.h b/avx2/symmetric.h
index 8f3c3c5..fa49963 100644
--- a/avx2/symmetric.h
+++ b/avx2/symmetric.h
@@ -6,21 +6,23 @@

#include "fips202.h"

-typedef keccak_state stream128_state;
-typedef keccak_state stream256_state;
+typedef shake128incctx stream128_state;
+typedef shake256incctx stream256_state;

#define dilithium_shake128_stream_init DILITHIUM_NAMESPACE(dilithium_shake128_stream_init)
-void dilithium_shake128_stream_init(keccak_state *state, const uint8_t seed[SEEDBYTES], uint16_t nonce);
+void dilithium_shake128_stream_init(shake128incctx *state, const uint8_t seed[SEEDBYTES], uint16_t nonce);

#define dilithium_shake256_stream_init DILITHIUM_NAMESPACE(dilithium_shake256_stream_init)
-void dilithium_shake256_stream_init(keccak_state *state, const uint8_t seed[CRHBYTES], uint16_t nonce);
+void dilithium_shake256_stream_init(shake256incctx *state, const uint8_t seed[CRHBYTES], uint16_t nonce);

#define STREAM128_BLOCKBYTES SHAKE128_RATE
#define STREAM256_BLOCKBYTES SHAKE256_RATE

#define stream128_init(STATE, SEED, NONCE) dilithium_shake128_stream_init(STATE, SEED, NONCE)
#define stream128_squeezeblocks(OUT, OUTBLOCKS, STATE) shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
+#define stream128_release(STATE) shake128_inc_ctx_release(STATE)
#define stream256_init(STATE, SEED, NONCE) dilithium_shake256_stream_init(STATE, SEED, NONCE)
#define stream256_squeezeblocks(OUT, OUTBLOCKS, STATE) shake256_squeezeblocks(OUT, OUTBLOCKS, STATE)
+#define stream256_release(STATE) shake256_inc_ctx_release(STATE)

#endif

Loading