41#ifdef HAVE_MLDSA_OPTIMIZATION
54#define MLDSA_MAX_SIGN_ATTEMPTS 814U
157 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 32U},
159 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 64U},
161 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08}, 32U},
163 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A}, 64U},
165 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0B}, 32U},
167 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0C}, 64U},
193 if (mprime == NULL) {
194 return CX_INVALID_PARAMETER;
196 if ((msg == NULL) && (msg_len > 0U)) {
197 return CX_INVALID_PARAMETER;
199 if ((ctx == NULL) && (ctx_len > 0U)) {
200 return CX_INVALID_PARAMETER;
202 if (ctx_len > 255U) {
203 return CX_INVALID_PARAMETER_SIZE;
206 mprime->
prefix[0] = 0x00U;
207 mprime->
prefix[1] = (uint8_t) ctx_len;
209 memcpy(&mprime->
prefix[2], ctx, ctx_len);
239 if (mprime == NULL) {
240 return CX_INVALID_PARAMETER;
242 if ((ph == NULL) && (ph_len > 0U)) {
243 return CX_INVALID_PARAMETER;
245 if ((ctx == NULL) && (ctx_len > 0U)) {
246 return CX_INVALID_PARAMETER;
248 if (ctx_len > 255U) {
249 return CX_INVALID_PARAMETER_SIZE;
253 return CX_INVALID_PARAMETER_VALUE;
256 return CX_INVALID_PARAMETER_SIZE;
259 mprime->
prefix[0] = 0x01U;
260 mprime->
prefix[1] = (uint8_t) ctx_len;
262 memcpy(&mprime->
prefix[2], ctx, ctx_len);
284 cx_sha3_t sha3_ctx = {0};
286 memset(&sha3_ctx, 0,
sizeof(sha3_ctx));
288 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, tr,
MLDSA_TRBYTES, NULL, 0);
289 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, mprime->
prefix, mprime->
prefix_len, NULL, 0);
294#ifndef HAVE_MLDSA_OPTIMIZATION
319 size_t *sig_actual_len,
321 const uint8_t *precomputed_mu,
331 const uint8_t *rnd_input = rnd;
333 cx_err_t error = CX_INTERNAL_ERROR;
335 uint32_t attempts = 0U;
337 if ((sig == NULL) || (sk == NULL) || (sig_actual_len == NULL)) {
338 error = CX_INVALID_PARAMETER;
341 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
342 error = CX_INVALID_PARAMETER;
347 error = CX_INVALID_PARAMETER;
350 if ((rnd == NULL) && (rnd_len != 0U)) {
351 error = CX_INVALID_PARAMETER;
356 error = CX_INVALID_PARAMETER_VALUE;
362 if (sk_len < p->sk_bytes) {
363 error = CX_INVALID_PARAMETER_SIZE;
366 if (sig_len < p->sig_bytes) {
367 error = CX_INVALID_PARAMETER_SIZE;
371 if (rnd_input == NULL) {
372 rnd_input = zero_rnd;
375 explicit_bzero(ws,
sizeof(*ws));
387 if (precomputed_mu != NULL) {
396 cx_sha3_t sha3_ctx = {0};
398 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, ws->
K,
MLDSA_SEEDBYTES, NULL, 0);
399 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, rnd_input,
MLDSA_RNDBYTES, NULL, 0);
406 uint16_t kappa_base = kappa;
412 for (uint8_t l = 0U; l < p->
l; l++) {
415 for (uint8_t k = 0U; k < p->
k; k++) {
416 uint16_t nonce = ((uint16_t) k << 8U) | (uint16_t) l;
421 kappa = (uint16_t) (kappa_base + p->
l);
428 for (uint8_t k = 0U; k < p->
k; k++) {
448 uint8_t z_reject = 0U;
449 for (uint8_t l = 0U; l < p->
l; l++) {
467 if (z_reject != 0U) {
477 uint32_t n_hints = 0U;
478 unsigned int hints_written = 0U;
483 for (uint8_t k = 0U; k < p->
k; k++) {
519 for (uint32_t j = 0U; j <
MLDSA_N; j++) {
523 if (hints_written >= p->
omega) {
527 sig_h[hints_written] = (uint8_t) j;
535 sig_h[p->
omega + k] = (uint8_t) hints_written;
538 if ((reject != 0U) || (n_hints > p->
omega)) {
551 error = CX_INTERNAL_ERROR;
554 explicit_bzero(zero_rnd,
sizeof(zero_rnd));
555 explicit_bzero(ws,
sizeof(*ws));
580 const uint8_t *precomputed_mu,
588 const uint8_t *sig_z = NULL;
589 const uint8_t *sig_h = NULL;
590 uint32_t k_offset = 0U;
591 cx_err_t error = CX_INTERNAL_ERROR;
593 if ((sig == NULL) || (pk == NULL)) {
594 error = CX_INVALID_PARAMETER;
597 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
598 error = CX_INVALID_PARAMETER;
603 error = CX_INVALID_PARAMETER_VALUE;
609 if (pk_len < p->pk_bytes) {
610 error = CX_INVALID_PARAMETER_SIZE;
613 if (sig_len < p->sig_bytes) {
614 error = CX_INVALID_PARAMETER_SIZE;
618 explicit_bzero(ws,
sizeof(*ws));
627 for (uint32_t i = 0U; i < p->
k; i++) {
628 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
629 if ((limit < k_offset) || (limit > p->
omega)) {
630 error = CX_INVALID_PARAMETER;
634 for (uint32_t j = k_offset; j < limit; j++) {
635 if ((j > k_offset) && (sig_h[j] <= sig_h[j - 1U])) {
636 error = CX_INVALID_PARAMETER;
643 for (uint32_t j = k_offset; j < p->
omega; j++) {
644 if (sig_h[j] != 0U) {
645 error = CX_INVALID_PARAMETER;
651 for (uint8_t j = 0U; j < p->
l; j++) {
654 error = CX_INVALID_PARAMETER;
660 if (precomputed_mu != NULL) {
674 for (uint8_t i = 0U; i < p->
k; i++) {
675 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
677 for (uint8_t j = 0U; j < p->
l; j++) {
678 uint16_t nonce = ((uint16_t) i << 8U) | (uint16_t) j;
698 explicit_bzero(&ws->
htmp,
sizeof(ws->
htmp));
699 for (uint32_t j = k_offset; j < limit; j++) {
719 error = CX_INVALID_PARAMETER;
726 explicit_bzero(ws,
sizeof(*ws));
749typedef struct MLDSA_sign_opt_workspace_s {
756 uint8_t ccomp[MLDSA_CCOMP_BYTES];
762 mldsa_smallpoly stmp;
766} MLDSA_sign_opt_workspace_t;
773 size_t *sig_actual_len,
775 const uint8_t *precomputed_mu,
782 MLDSA_sign_opt_workspace_t ws_local = {0};
783 MLDSA_sign_opt_workspace_t *ws = &ws_local;
785 const uint8_t *rnd_input = rnd;
787 cx_err_t error = CX_INTERNAL_ERROR;
789 uint32_t attempts = 0U;
791 if ((sig == NULL) || (sk == NULL) || (sig_actual_len == NULL)) {
792 error = CX_INVALID_PARAMETER;
795 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
796 error = CX_INVALID_PARAMETER;
800 error = CX_INVALID_PARAMETER;
803 if ((rnd == NULL) && (rnd_len != 0U)) {
804 error = CX_INVALID_PARAMETER;
808 error = CX_INVALID_PARAMETER_VALUE;
814 if (sk_len < p->sk_bytes) {
815 error = CX_INVALID_PARAMETER_SIZE;
818 if (sig_len < p->sig_bytes) {
819 error = CX_INVALID_PARAMETER_SIZE;
823 if (rnd_input == NULL) {
824 rnd_input = zero_rnd;
827 explicit_bzero(ws,
sizeof(*ws));
839 if (precomputed_mu != NULL) {
848 cx_sha3_t sha3_ctx = {0};
850 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, ws->K,
MLDSA_SEEDBYTES, NULL, 0);
851 cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, rnd_input,
MLDSA_RNDBYTES, NULL, 0);
861 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
862 memset(ws->wcomp[k_idx], 0, MLDSA_WCOMP_BYTES);
866 for (uint8_t l_idx = 0U; l_idx < p->
l; l_idx++) {
867 MLDSA_LOWRAM_sample_gamma1(
868 &ws->polybuf.full, ws->rhoprime, (uint16_t) (kappa + l_idx), p->
gamma1);
871 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
872 uint16_t nonce = ((uint16_t) k_idx << 8U) | (uint16_t) l_idx;
873 MLDSA_LOWRAM_expand_aij_accum(ws->wcomp[k_idx], &ws->polybuf.full, ws->rho, nonce);
876 kappa += (uint16_t) p->
l;
879 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
880 MLDSA_LOWRAM_polyw_unpack(&ws->polybuf.full, ws->wcomp[k_idx]);
883 MLDSA_LOWRAM_polyw_pack(ws->wcomp[k_idx], &ws->polybuf.full);
884 MLDSA_LOWRAM_poly_highbits(&ws->polybuf.full, &ws->polybuf.full, p->
gamma2);
899 MLDSA_LOWRAM_challenge_compress(ws->ccomp, &ws->polybuf.full, p->
tau);
902 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
906 uint8_t z_reject = 0U;
907 for (uint8_t l_idx = 0U; l_idx < p->
l; l_idx++) {
910 MLDSA_LOWRAM_challenge_decompress(&ws->polybuf.full, ws->ccomp, p->
tau);
911 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
915 MLDSA_SMALLPOLY_unpack_eta(&ws->polybuf.small.stmp,
918 MLDSA_SMALLPOLY_ntt(ws->polybuf.small.stmp.coeffs);
921 MLDSA_SMALLPOLY_basemul_invntt(
922 &ws->polybuf.full, &ws->polybuf.small.scp, &ws->polybuf.small.stmp);
925 MLDSA_LOWRAM_sample_gamma1_add(&ws->polybuf.full,
928 (uint16_t) (kappa - (uint16_t) p->
l + l_idx),
943 if (z_reject != 0U) {
950 uint8_t r0_reject = 0U;
951 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
953 MLDSA_LOWRAM_challenge_decompress(&ws->polybuf.full, ws->ccomp, p->
tau);
954 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
957 MLDSA_SMALLPOLY_unpack_eta(&ws->polybuf.small.stmp,
960 MLDSA_SMALLPOLY_ntt(ws->polybuf.small.stmp.coeffs);
963 MLDSA_SMALLPOLY_basemul_invntt(
964 &ws->polybuf.full, &ws->polybuf.small.scp, &ws->polybuf.small.stmp);
967 MLDSA_LOWRAM_polyw_sub(&ws->polybuf.full, ws->wcomp[k_idx], &ws->polybuf.full);
971 MLDSA_LOWRAM_polyw_pack(ws->wcomp[k_idx], &ws->polybuf.full);
975 MLDSA_LOWRAM_poly_r0(&ws->polybuf.full,
985 if (r0_reject != 0U) {
992 uint32_t n_hints = 0U;
994 unsigned int hints_written = 0U;
1001 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
1002 MLDSA_LOWRAM_schoolbook_t0(&ws->polybuf.full,
1015 uint32_t row_hints = MLDSA_LOWRAM_make_hint(
1021 n_hints += row_hints;
1023 if (n_hints > p->
omega) {
1031 for (uint32_t j = 0U; j <
MLDSA_N; j++) {
1032 if (ws->polybuf.full.coeffs[j] != 0) {
1033 sig_h[hints_written] = (uint8_t) j;
1037 sig_h[p->
omega + k_idx] = (uint8_t) hints_written;
1048 while (hints_written < p->omega) {
1049 sig_h[hints_written] = 0U;
1063 error = CX_INTERNAL_ERROR;
1066 explicit_bzero(zero_rnd,
sizeof(zero_rnd));
1067 explicit_bzero(ws,
sizeof(*ws));
1074typedef struct MLDSA_verify_opt_workspace_s {
1076 uint8_t ctilde[64U];
1078 uint8_t ccomp[MLDSA_CCOMP_BYTES];
1079 uint8_t wcomp[MLDSA_WCOMP_BYTES];
1081 uint8_t ctilde2[64U];
1082 uint8_t h_indices[MLDSA_MAX_OMEGA];
1088} MLDSA_verify_opt_workspace_t;
1096 const uint8_t *precomputed_mu,
1101 MLDSA_verify_opt_workspace_t ws_local = {0};
1102 MLDSA_verify_opt_workspace_t *ws = &ws_local;
1104 const uint8_t *sig_z = NULL;
1105 const uint8_t *sig_h = NULL;
1106 uint32_t k_offset = 0U;
1107 cx_err_t error = CX_INTERNAL_ERROR;
1109 if ((sig == NULL) || (pk == NULL)) {
1110 error = CX_INVALID_PARAMETER;
1113 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
1114 error = CX_INVALID_PARAMETER;
1118 error = CX_INVALID_PARAMETER_VALUE;
1124 if (pk_len < p->pk_bytes) {
1125 error = CX_INVALID_PARAMETER_SIZE;
1128 if (sig_len < p->sig_bytes) {
1129 error = CX_INVALID_PARAMETER_SIZE;
1133 explicit_bzero(ws,
sizeof(*ws));
1142 for (uint32_t i = 0U; i < p->
k; i++) {
1143 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
1144 if ((limit < k_offset) || (limit > p->
omega)) {
1145 error = CX_INVALID_PARAMETER;
1148 for (uint32_t j = k_offset; j < limit; j++) {
1149 if ((j > k_offset) && (sig_h[j] <= sig_h[j - 1U])) {
1150 error = CX_INVALID_PARAMETER;
1156 for (uint32_t j = k_offset; j < p->
omega; j++) {
1157 if (sig_h[j] != 0U) {
1158 error = CX_INVALID_PARAMETER;
1164 for (uint8_t j = 0U; j < p->
l; j++) {
1167 error = CX_INVALID_PARAMETER;
1173 if (precomputed_mu != NULL) {
1183 MLDSA_LOWRAM_challenge_compress(ws->ccomp, &ws->tmp, p->
tau);
1187 for (uint8_t i = 0U; i < p->
k; i++) {
1188 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
1191 memset(ws->wcomp, 0, MLDSA_WCOMP_BYTES);
1192 for (uint8_t j = 0U; j < p->
l; j++) {
1193 uint16_t nonce = ((uint16_t) i << 8U) | (uint16_t) j;
1197 MLDSA_LOWRAM_expand_aij_accum(ws->wcomp, &ws->tmp, ws->rho, nonce);
1201 MLDSA_LOWRAM_polyw_unpack(&ws->tmp, ws->wcomp);
1206 MLDSA_LOWRAM_schoolbook_t1(&ws->ct1,
1215 uint32_t num_hints = limit - k_offset;
1216 for (uint32_t j = 0U; j < num_hints; j++) {
1217 ws->h_indices[j] = sig_h[k_offset + j];
1222 MLDSA_LOWRAM_use_hint_indices(&ws->tmp, &ws->tmp, ws->h_indices, num_hints, p->
gamma2);
1237 if (memcmp(ws->ctilde, ws->ctilde2, p->
ctilde_bytes) != 0) {
1238 error = CX_INVALID_PARAMETER;
1245 explicit_bzero(ws,
sizeof(*ws));
1260 cx_err_t error = CX_INTERNAL_ERROR;
1263 if ((pk == NULL) || (sk == NULL)) {
1264 error = CX_INVALID_PARAMETER;
1269 error = CX_INVALID_PARAMETER_VALUE;
1277 explicit_bzero(seed,
sizeof(seed));
1286 size_t *sig_actual_len,
1299 if (error != CX_OK) {
1305 sig, sig_len, sig_actual_len, &mprime, NULL, rnd,
sizeof(rnd), sk, sk_len, param);
1308 explicit_bzero(rnd,
sizeof(rnd));
1328 if (error != CX_OK) {
1340 size_t *sig_actual_len,
1354 if (error != CX_OK) {
1360 sig, sig_len, sig_actual_len, &mprime, NULL, rnd,
sizeof(rnd), sk, sk_len, param);
1363 explicit_bzero(rnd,
sizeof(rnd));
1384 if (error != CX_OK) {
struct MLDSA_sign_stack_workspace_s MLDSA_sign_stack_workspace_t
Stack-allocated workspace for MLDSA_internal_sign_core.
static cx_err_t mldsa_format_message_prehash(MLDSA_formatted_message_t *mprime, const uint8_t *ctx, size_t ctx_len, MLDSA_prehash_t prehash_alg, const uint8_t *ph, size_t ph_len)
Formats a pre-hashed message into M' for HashML-DSA (FIPS 204, Section 5.4).
cx_err_t MLDSA_verify_prehash(const uint8_t *sig, size_t sig_len, const uint8_t *ph, size_t ph_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *pk, size_t pk_len, MLDSA_prehash_t prehash_alg, MLDSA_param_t param)
HashML-DSA pre-hash signature verification (FIPS 204, Algorithm 5).
cx_err_t MLDSA_verify(const uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *pk, size_t pk_len, MLDSA_param_t param)
ML-DSA signature verification.
#define MLDSA_MAX_SIGN_ATTEMPTS
cx_err_t MLDSA_keygen(uint8_t *pk, size_t pk_len, uint8_t *sk, size_t sk_len, MLDSA_param_t param)
Generates an ML-DSA key pair.
struct MLDSA_verify_stack_workspace_s MLDSA_verify_stack_workspace_t
Stack-allocated workspace for MLDSA_internal_verify_core.
static cx_err_t mldsa_format_message_pure(MLDSA_formatted_message_t *mprime, const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, size_t msg_len)
Formats a pure (non-pre-hashed) message into M' (FIPS 204, Section 5.2).
cx_err_t MLDSA_sign_prehash(uint8_t *sig, size_t sig_len, size_t *sig_actual_len, const uint8_t *ph, size_t ph_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *sk, size_t sk_len, MLDSA_prehash_t prehash_alg, MLDSA_param_t param)
HashML-DSA pre-hash signature generation (FIPS 204, Algorithm 4).
struct MLDSA_prehash_info_s MLDSA_prehash_info_t
DER-encoded OID and expected output length for each pre-hash algorithm. (FIPS 204,...
cx_err_t MLDSA_internal_verify_core(const uint8_t *sig, size_t sig_len, const MLDSA_formatted_message_t *formatted_mprime, const uint8_t *precomputed_mu, const uint8_t *pk, size_t pk_len, MLDSA_param_t param)
Core ML-DSA verification routine (FIPS 204, Algorithms 3 & 8).
struct MLDSA_formatted_message_s MLDSA_formatted_message_t
static const MLDSA_prehash_info_t MLDSA_PREHASH_INFO[MLDSA_NUM_PREHASH_ALGS]
cx_err_t MLDSA_sign(uint8_t *sig, size_t sig_len, size_t *sig_actual_len, const uint8_t *msg, size_t msg_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *sk, size_t sk_len, MLDSA_param_t param)
ML-DSA signature generation.
static void mldsa_compute_mu(uint8_t mu[MLDSA_CRHBYTES], const uint8_t tr[MLDSA_TRBYTES], const MLDSA_formatted_message_t *mprime)
Computes mu = SHAKE256(tr || M', 64) for a formatted message M'.
cx_err_t MLDSA_internal_sign_core(uint8_t *sig, size_t sig_len, size_t *sig_actual_len, const MLDSA_formatted_message_t *formatted_mprime, const uint8_t *precomputed_mu, uint8_t *rnd, size_t rnd_len, const uint8_t *sk, size_t sk_len, MLDSA_param_t param)
Core ML-DSA signing routine (FIPS 204, Algorithms 2 & 7).
cx_err_t MLDSA_internal_keygen(uint8_t *pk, size_t pk_len, uint8_t *sk, size_t sk_len, const uint8_t seed[MLDSA_SEEDBYTES], MLDSA_param_t param)
Generates an ML-DSA key pair from a seed (deterministic).
ML-DSA low-RAM helper functions.
uint32_t MLDSA_PACK_polyw1(uint8_t *r, const mldsa_poly *a, int32_t gamma2)
Bit-pack polynomial w1 with coefficients fitting in ceil(log2((q-1)/(2*gamma2))) bits.
uint32_t MLDSA_PACK_unpack_polyeta(mldsa_poly *r, const uint8_t *a, uint8_t eta)
Unpack polynomial with coefficients in [-eta, eta].
void MLDSA_PACK_unpack_polyt0(mldsa_poly *r, const uint8_t a[MLDSA_POLYT0_PACKEDBYTES])
Unpack polynomial t0 from bytes.
uint32_t MLDSA_PACK_unpack_polyz(mldsa_poly *r, const uint8_t *a, int32_t gamma1)
Unpack polynomial z.
void MLDSA_PACK_unpack_polyt1(mldsa_poly *r, const uint8_t a[MLDSA_POLYT1_PACKEDBYTES])
Unpack polynomial t1 from bytes.
uint32_t MLDSA_PACK_polyz(uint8_t *r, const mldsa_poly *a, int32_t gamma1)
Bit-pack polynomial z with coefficients in [-(gamma1-1), gamma1].
void MLDSA_POLY_reduce(mldsa_poly *a)
Applies reduce32 to all coefficients of a polynomial.
int MLDSA_POLY_chknorm(const mldsa_poly *a, int32_t B)
Checks infinity norm of polynomial against bound B.
void MLDSA_POLY_ntt(mldsa_poly *a)
Forward NTT in place.
void MLDSA_POLY_sub(mldsa_poly *a, const mldsa_poly *b)
Subtracts polynomial b from polynomial a in place.
void MLDSA_POLY_shiftl(mldsa_poly *a)
Shifts all coefficients left by D bits.
void MLDSA_POLY_caddq_all(mldsa_poly *a)
Applies caddq to all coefficients of a polynomial.
void MLDSA_POLY_add(mldsa_poly *a, const mldsa_poly *b)
Adds polynomial b to polynomial a in place.
void MLDSA_POLY_invntt_tomont(mldsa_poly *a)
Inverse NTT and multiply by Montgomery factor.
void MLDSA_POLY_pointwise_montgomery(mldsa_poly *c, const mldsa_poly *a, const mldsa_poly *b, int first)
Pointwise multiplication (Montgomery) with accumulation.
void MLDSA_POLYVEC_invntt_tomont_k(mldsa_polyveck *v, uint8_t k)
Apply inverse NTT to all polynomials in a K-vector.
void MLDSA_POLYVEC_reduce_k(mldsa_polyveck *v, uint8_t k)
Apply reduce to all polynomials in a K-vector.
void MLDSA_POLYVEC_caddq_k(mldsa_polyveck *v, uint8_t k)
Apply caddq to all polynomials in a K-vector.
void MLDSA_ROUNDING_poly_use_hint(mldsa_poly *b, const mldsa_poly *a, const mldsa_poly *h, int32_t gamma2)
Applies use_hint to all coefficients of a polynomial.
void MLDSA_ROUNDING_poly_decompose(mldsa_poly *a1, mldsa_poly *a0, const mldsa_poly *a, int32_t gamma2)
Applies decompose to all coefficients of a polynomial.
uint32_t MLDSA_ROUNDING_make_hint(int32_t a0, int32_t a1, int32_t gamma2)
Compute hint bit. Returns 1 if adding ct0 to w - ct0 would change the high bits (i....
void MLDSA_SAMPLE_uniform(mldsa_poly *a, const uint8_t seed[MLDSA_SEEDBYTES], uint16_t nonce)
Sample polynomial with uniformly random coefficients in [0, q-1] by performing rejection sampling on ...
void MLDSA_SAMPLE_challenge(mldsa_poly *c, const uint8_t *seed, size_t seedlen, uint8_t tau)
Sample challenge polynomial with TAU coefficients in {-1, +1}.
void MLDSA_SAMPLE_gamma1(mldsa_poly *a, const uint8_t seed[MLDSA_CRHBYTES], uint16_t nonce, int32_t gamma1)
Sample polynomial with coefficients in [-(gamma1-1), gamma1] from SHAKE256(seed||nonce).
ML-DSA small polynomial type and NTT mod 3329 (low-RAM optimization).
void MLDSA_UTIL_shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
SHAKE256 hash wrapper.
void MLDSA_UTIL_shake256_two(uint8_t *out, size_t outlen, const uint8_t *in1, size_t in1len, const uint8_t *in2, size_t in2len)
SHAKE256 with two inputs concatenated.
#define MLDSA_POLYT0_PACKEDBYTES
#define MLDSA_POLYT1_PACKEDBYTES
enum MLDSA_prehash_e MLDSA_prehash_t
Hash algorithm selector for HashML-DSA pre-hash signatures.
#define MLDSA_PREHASH_OID_LEN
ML-DSA (Module-Lattice Digital Signature Algorithm) public API.
const MLDSA_param_info_t MLDSA_PARAM[MLDSA_NUM_PARAM_SETS]
Lookup table of ML-DSA parameter sets indexed by MLDSA_param_t.
enum MLDSA_param_e MLDSA_param_t
ML-DSA parameter set selector.
#define MLDSA_NUM_PARAM_SETS
Random Number Generation.
SHA-3 (Secure Hash Algorithm 3)
ML-DSA parameter set descriptor holding all derived sizes.
uint16_t polyvech_packed_bytes
uint16_t polyz_packed_bytes
uint16_t polyeta_packed_bytes
uint16_t polyw1_packed_bytes
DER-encoded OID and expected output length for each pre-hash algorithm. (FIPS 204,...
uint8_t oid[MLDSA_PREHASH_OID_LEN]
Stack-allocated workspace for MLDSA_internal_sign_core.
uint8_t rho[MLDSA_SEEDBYTES]
uint8_t K[MLDSA_SEEDBYTES]
uint8_t w1_packed[MLDSA_MAX_K *192U]
uint8_t mu[MLDSA_CRHBYTES]
uint8_t tr[MLDSA_TRBYTES]
uint8_t rhoprime[MLDSA_CRHBYTES]
Stack-allocated workspace for MLDSA_internal_verify_core.
MLDSA_verify_phase_overlay_t overlay
uint8_t mu[MLDSA_CRHBYTES]
uint8_t rho[MLDSA_SEEDBYTES]
uint8_t w1_packed[MLDSA_MAX_K *192U]
Polynomial with MLDSA_N int32_t coefficients.
Polynomial vector of up to MLDSA_MAX_K polynomials.
mldsa_poly vec[MLDSA_MAX_K]
Phase-overlaid scratch union for MLDSA_internal_verify_core.
struct MLDSA_verify_phase_overlay_t::@3 az_phase
Az product loop temporaries.
uint8_t tr[MLDSA_TRBYTES]
struct MLDSA_verify_phase_overlay_t::@2 setup_phase
Early-phase temporary used to derive mu.