diff --git a/wolfcrypt/src/dilithium.c b/wolfcrypt/src/dilithium.c index 4bf1cdd223..d3158dc50c 100644 --- a/wolfcrypt/src/dilithium.c +++ b/wolfcrypt/src/dilithium.c @@ -60,7 +60,11 @@ * is considerably slower. * WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC Default: OFF * Compiles signature implementation that uses smaller amounts of memory but - * is considerably slower. Allocates vectors for decoded parameters. + * is considerably slower. Allocates vectors and decodes private key data + * into them upfront. + * WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A Default: OFF + * Compiles signature implementation that uses smaller amounts of memory but + * is slower. Allocates matrix A and calculates it upfront. * * WOLFSSL_DILITHIUM_ALIGNMENT Default: 8 * Use to indicate whether loading and storing of words needs to be aligned. @@ -145,6 +149,13 @@ !defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) #define WOLFSSL_DILITHIUM_SIGN_SMALL_MEM #endif +#if defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A) && \ + !defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) + #define WOLFSSL_DILITHIUM_SIGN_SMALL_MEM + #ifdef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC + #error "PRECALC and PRECALC_A is equivalent to non small mem" + #endif +#endif #ifdef WOLFSSL_WC_DILITHIUM @@ -2742,7 +2753,8 @@ static void dilithium_decompose_q32(sword32 r, sword32* r0, sword32* r1) #ifndef WOLFSSL_DILITHIUM_NO_SIGN -#ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM +#if !defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) || \ + defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A) /* Decompose vector of polynomials into high and low based on GAMMA2. * * @param [in] r Vector of polynomials to decompose. @@ -5766,9 +5778,11 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, /* y-l, w0-k, w1-k, c-1, z-1, A-1 */ allocSz = params->s1Sz + params->s2Sz + params->s2Sz + DILITHIUM_POLY_SIZE + DILITHIUM_POLY_SIZE + DILITHIUM_POLY_SIZE; -#ifdef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC + #ifdef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC allocSz += params->s1Sz + params->s2Sz + params->s2Sz; -#endif + #elif defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A) + allocSz += params->aSz - DILITHIUM_POLY_SIZE; + #endif y = (sword32*)XMALLOC(allocSz, NULL, DYNAMIC_TYPE_DILITHIUM); if (y == NULL) { ret = MEMORY_E; @@ -5780,7 +5794,11 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, z = c + DILITHIUM_N; a = z + DILITHIUM_N; ct0 = z; + #ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A y_ntt = z; + #else + y_ntt = w0; + #endif #ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC s1 = z; s2 = z; @@ -5811,6 +5829,13 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, if (ret == 0) { dilithium_make_priv_vecs(key, s1, s2, t0); } +#endif +#ifdef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A + if (ret == 0) { + /* Step 5: Create the matrix A from the public seed. */ + ret = dilithium_expand_a(&key->shake, pub_seed, params->k, + params->l, a); + } #endif if (ret == 0) { word16 kappa = 0; @@ -5823,12 +5848,14 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, byte* commit = sig; byte r; byte s; - byte aseed[DILITHIUM_GEN_A_SEED_SZ]; sword32 hi; - sword32* at = a; - sword32* wt = w; sword32* w0t = w0; sword32* w1t = w1; + #ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A + byte aseed[DILITHIUM_GEN_A_SEED_SZ]; + sword32* at = a; + sword32* wt = w; + #endif valid = 1; /* Step 12: Compute vector y from private random seed and kappa. */ @@ -5839,6 +5866,7 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, (1 << params->gamma1_bits) - params->beta); #endif + #ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC_A /* Step 5: Create the matrix A from the public seed. */ /* Copy the seed into a buffer that has space for s and r. */ XMEMCPY(aseed, pub_seed, DILITHIUM_PUB_SEED_SZ); @@ -5906,6 +5934,16 @@ static int dilithium_sign_msg_with_seed(dilithium_key* key, const byte* seed, w0t += DILITHIUM_N; w1t += DILITHIUM_N; } + #else + /* Step 13: NTT-1(A o NTT(y)) */ + XMEMCPY(y_ntt, y, params->s1Sz); + dilithium_vec_ntt(y_ntt, params->l); + dilithium_matrix_mul(w, a, y_ntt, params->k, params->l); + dilithium_vec_invntt(w, params->k); + /* Step 14, Step 22: Make values positive and decompose. */ + dilithium_vec_make_pos(w, params->k); + dilithium_vec_decompose(w, params->k, params->gamma2, w0, w1); + #endif if ((ret == 0) && valid) { sword32* yt = y; #ifndef WOLFSSL_DILITHIUM_SIGN_SMALL_MEM_PRECALC