41#ifdef HAVE_MLDSA_OPTIMIZATION
54#define MLDSA_MAX_SIGN_ATTEMPTS 814U
145 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 32U},
147 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 64U},
149 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08}, 32U},
151 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A}, 64U},
153 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0B}, 32U},
155 {{0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0C}, 64U},
181 if (mprime == NULL) {
182 return CX_INVALID_PARAMETER;
184 if ((msg == NULL) && (msg_len > 0U)) {
185 return CX_INVALID_PARAMETER;
187 if ((ctx == NULL) && (ctx_len > 0U)) {
188 return CX_INVALID_PARAMETER;
190 if (ctx_len > 255U) {
191 return CX_INVALID_PARAMETER_SIZE;
194 mprime->
prefix[0] = 0x00U;
195 mprime->
prefix[1] = (uint8_t) ctx_len;
197 memcpy(&mprime->
prefix[2], ctx, ctx_len);
227 if (mprime == NULL) {
228 return CX_INVALID_PARAMETER;
230 if ((ph == NULL) && (ph_len > 0U)) {
231 return CX_INVALID_PARAMETER;
233 if ((ctx == NULL) && (ctx_len > 0U)) {
234 return CX_INVALID_PARAMETER;
236 if (ctx_len > 255U) {
237 return CX_INVALID_PARAMETER_SIZE;
241 return CX_INVALID_PARAMETER_VALUE;
244 return CX_INVALID_PARAMETER_SIZE;
247 mprime->
prefix[0] = 0x01U;
248 mprime->
prefix[1] = (uint8_t) ctx_len;
250 memcpy(&mprime->
prefix[2], ctx, ctx_len);
272 cx_sha3_t sha3_ctx = {0};
275 memset(&sha3_ctx, 0,
sizeof(sha3_ctx));
276 error = cx_shake256_init_no_throw(&sha3_ctx,
MLDSA_CRHBYTES * 8U);
277 if (error != CX_OK) {
280 error = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, tr,
MLDSA_TRBYTES, NULL, 0);
281 if (error != CX_OK) {
285 = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, mprime->
prefix, mprime->
prefix_len, NULL, 0);
286 if (error != CX_OK) {
289 return cx_hash_no_throw(
293#ifndef HAVE_MLDSA_OPTIMIZATION
318 size_t *sig_actual_len,
320 const uint8_t *precomputed_mu,
330 const uint8_t *rnd_input = rnd;
332 cx_err_t error = CX_INTERNAL_ERROR;
334 uint32_t attempts = 0U;
336 if ((sig == NULL) || (sk == NULL) || (sig_actual_len == NULL)) {
337 error = CX_INVALID_PARAMETER;
340 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
341 error = CX_INVALID_PARAMETER;
346 error = CX_INVALID_PARAMETER;
349 if ((rnd == NULL) && (rnd_len != 0U)) {
350 error = CX_INVALID_PARAMETER;
355 error = CX_INVALID_PARAMETER_VALUE;
361 if (sk_len < p->sk_bytes) {
362 error = CX_INVALID_PARAMETER_SIZE;
365 if (sig_len < p->sig_bytes) {
366 error = CX_INVALID_PARAMETER_SIZE;
370 if (rnd_input == NULL) {
371 rnd_input = zero_rnd;
374 explicit_bzero(ws,
sizeof(*ws));
386 if (precomputed_mu != NULL) {
391 if (error != CX_OK) {
398 cx_sha3_t sha3_ctx = {0};
399 error = cx_shake256_init_no_throw(&sha3_ctx,
MLDSA_CRHBYTES * 8U);
400 if (error != CX_OK) {
403 error = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, ws->
K,
MLDSA_SEEDBYTES, NULL, 0);
404 if (error != CX_OK) {
407 error = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, rnd_input,
MLDSA_RNDBYTES, NULL, 0);
408 if (error != CX_OK) {
411 error = cx_hash_no_throw(
413 if (error != CX_OK) {
420 uint16_t kappa_base = kappa;
426 for (uint8_t l = 0U; l < p->
l; l++) {
429 for (uint8_t k = 0U; k < p->
k; k++) {
430 uint16_t nonce = ((uint16_t) k << 8U) | (uint16_t) l;
435 kappa = (uint16_t) (kappa_base + p->
l);
442 for (uint8_t k = 0U; k < p->
k; k++) {
455 if (error != CX_OK) {
465 uint8_t z_reject = 0U;
466 for (uint8_t l = 0U; l < p->
l; l++) {
484 if (z_reject != 0U) {
494 uint32_t n_hints = 0U;
495 unsigned int hints_written = 0U;
500 for (uint8_t k = 0U; k < p->
k; k++) {
536 for (uint32_t j = 0U; j <
MLDSA_N; j++) {
540 if (hints_written >= p->
omega) {
544 sig_h[hints_written] = (uint8_t) j;
552 sig_h[p->
omega + k] = (uint8_t) hints_written;
555 if ((reject != 0U) || (n_hints > p->
omega)) {
568 error = CX_INTERNAL_ERROR;
571 explicit_bzero(zero_rnd,
sizeof(zero_rnd));
572 explicit_bzero(ws,
sizeof(*ws));
597 const uint8_t *precomputed_mu,
605 const uint8_t *sig_z = NULL;
606 const uint8_t *sig_h = NULL;
607 uint32_t k_offset = 0U;
608 cx_err_t error = CX_INTERNAL_ERROR;
610 if ((sig == NULL) || (pk == NULL)) {
611 error = CX_INVALID_PARAMETER;
614 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
615 error = CX_INVALID_PARAMETER;
620 error = CX_INVALID_PARAMETER_VALUE;
626 if (pk_len < p->pk_bytes) {
627 error = CX_INVALID_PARAMETER_SIZE;
630 if (sig_len < p->sig_bytes) {
631 error = CX_INVALID_PARAMETER_SIZE;
635 explicit_bzero(ws,
sizeof(*ws));
644 for (uint32_t i = 0U; i < p->
k; i++) {
645 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
646 if ((limit < k_offset) || (limit > p->
omega)) {
647 error = CX_INVALID_PARAMETER;
651 for (uint32_t j = k_offset; j < limit; j++) {
652 if ((j > k_offset) && (sig_h[j] <= sig_h[j - 1U])) {
653 error = CX_INVALID_PARAMETER;
660 for (uint32_t j = k_offset; j < p->
omega; j++) {
661 if (sig_h[j] != 0U) {
662 error = CX_INVALID_PARAMETER;
668 for (uint8_t j = 0U; j < p->
l; j++) {
671 error = CX_INVALID_PARAMETER;
677 if (precomputed_mu != NULL) {
683 if (error != CX_OK) {
694 for (uint8_t i = 0U; i < p->
k; i++) {
695 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
697 for (uint8_t j = 0U; j < p->
l; j++) {
698 uint16_t nonce = ((uint16_t) i << 8U) | (uint16_t) j;
718 explicit_bzero(&ws->
htmp,
sizeof(ws->
htmp));
719 for (uint32_t j = k_offset; j < limit; j++) {
736 if (error != CX_OK) {
742 error = CX_INVALID_PARAMETER;
749 explicit_bzero(ws,
sizeof(*ws));
772typedef struct MLDSA_sign_opt_workspace_s {
779 uint8_t ccomp[MLDSA_CCOMP_BYTES];
785 mldsa_smallpoly stmp;
789} MLDSA_sign_opt_workspace_t;
796 size_t *sig_actual_len,
798 const uint8_t *precomputed_mu,
805 MLDSA_sign_opt_workspace_t ws_local = {0};
806 MLDSA_sign_opt_workspace_t *ws = &ws_local;
808 const uint8_t *rnd_input = rnd;
810 cx_err_t error = CX_INTERNAL_ERROR;
812 uint32_t attempts = 0U;
814 if ((sig == NULL) || (sk == NULL) || (sig_actual_len == NULL)) {
815 error = CX_INVALID_PARAMETER;
818 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
819 error = CX_INVALID_PARAMETER;
823 error = CX_INVALID_PARAMETER;
826 if ((rnd == NULL) && (rnd_len != 0U)) {
827 error = CX_INVALID_PARAMETER;
831 error = CX_INVALID_PARAMETER_VALUE;
837 if (sk_len < p->sk_bytes) {
838 error = CX_INVALID_PARAMETER_SIZE;
841 if (sig_len < p->sig_bytes) {
842 error = CX_INVALID_PARAMETER_SIZE;
846 if (rnd_input == NULL) {
847 rnd_input = zero_rnd;
850 explicit_bzero(ws,
sizeof(*ws));
862 if (precomputed_mu != NULL) {
867 if (error != CX_OK) {
874 cx_sha3_t sha3_ctx = {0};
875 error = cx_shake256_init_no_throw(&sha3_ctx,
MLDSA_CRHBYTES * 8U);
876 if (error != CX_OK) {
879 error = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, ws->K,
MLDSA_SEEDBYTES, NULL, 0);
880 if (error != CX_OK) {
883 error = cx_hash_no_throw((cx_hash_t *) &sha3_ctx, 0, rnd_input,
MLDSA_RNDBYTES, NULL, 0);
884 if (error != CX_OK) {
887 error = cx_hash_no_throw(
889 if (error != CX_OK) {
899 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
900 memset(ws->wcomp[k_idx], 0, MLDSA_WCOMP_BYTES);
904 for (uint8_t l_idx = 0U; l_idx < p->
l; l_idx++) {
905 MLDSA_LOWRAM_sample_gamma1(
906 &ws->polybuf.full, ws->rhoprime, (uint16_t) (kappa + l_idx), p->
gamma1);
909 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
910 uint16_t nonce = ((uint16_t) k_idx << 8U) | (uint16_t) l_idx;
911 MLDSA_LOWRAM_expand_aij_accum(ws->wcomp[k_idx], &ws->polybuf.full, ws->rho, nonce);
914 kappa += (uint16_t) p->
l;
917 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
918 MLDSA_LOWRAM_polyw_unpack(&ws->polybuf.full, ws->wcomp[k_idx]);
921 MLDSA_LOWRAM_polyw_pack(ws->wcomp[k_idx], &ws->polybuf.full);
922 MLDSA_LOWRAM_poly_highbits(&ws->polybuf.full, &ws->polybuf.full, p->
gamma2);
935 if (error != CX_OK) {
940 MLDSA_LOWRAM_challenge_compress(ws->ccomp, &ws->polybuf.full, p->
tau);
943 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
947 uint8_t z_reject = 0U;
948 for (uint8_t l_idx = 0U; l_idx < p->
l; l_idx++) {
951 MLDSA_LOWRAM_challenge_decompress(&ws->polybuf.full, ws->ccomp, p->
tau);
952 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
956 MLDSA_SMALLPOLY_unpack_eta(&ws->polybuf.small.stmp,
959 MLDSA_SMALLPOLY_ntt(ws->polybuf.small.stmp.coeffs);
962 MLDSA_SMALLPOLY_basemul_invntt(
963 &ws->polybuf.full, &ws->polybuf.small.scp, &ws->polybuf.small.stmp);
966 MLDSA_LOWRAM_sample_gamma1_add(&ws->polybuf.full,
969 (uint16_t) (kappa - (uint16_t) p->
l + l_idx),
984 if (z_reject != 0U) {
991 uint8_t r0_reject = 0U;
992 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
994 MLDSA_LOWRAM_challenge_decompress(&ws->polybuf.full, ws->ccomp, p->
tau);
995 MLDSA_SMALLPOLY_ntt_copy(&ws->polybuf.small.scp, &ws->polybuf.full);
998 MLDSA_SMALLPOLY_unpack_eta(&ws->polybuf.small.stmp,
1001 MLDSA_SMALLPOLY_ntt(ws->polybuf.small.stmp.coeffs);
1004 MLDSA_SMALLPOLY_basemul_invntt(
1005 &ws->polybuf.full, &ws->polybuf.small.scp, &ws->polybuf.small.stmp);
1008 MLDSA_LOWRAM_polyw_sub(&ws->polybuf.full, ws->wcomp[k_idx], &ws->polybuf.full);
1012 MLDSA_LOWRAM_polyw_pack(ws->wcomp[k_idx], &ws->polybuf.full);
1016 MLDSA_LOWRAM_poly_r0(&ws->polybuf.full,
1026 if (r0_reject != 0U) {
1033 uint32_t n_hints = 0U;
1034 uint8_t reject = 0U;
1035 unsigned int hints_written = 0U;
1042 for (uint8_t k_idx = 0U; k_idx < p->
k; k_idx++) {
1043 MLDSA_LOWRAM_schoolbook_t0(&ws->polybuf.full,
1056 uint32_t row_hints = MLDSA_LOWRAM_make_hint(
1062 n_hints += row_hints;
1064 if (n_hints > p->
omega) {
1072 for (uint32_t j = 0U; j <
MLDSA_N; j++) {
1073 if (ws->polybuf.full.coeffs[j] != 0) {
1074 sig_h[hints_written] = (uint8_t) j;
1078 sig_h[p->
omega + k_idx] = (uint8_t) hints_written;
1089 while (hints_written < p->omega) {
1090 sig_h[hints_written] = 0U;
1104 error = CX_INTERNAL_ERROR;
1107 explicit_bzero(zero_rnd,
sizeof(zero_rnd));
1108 explicit_bzero(ws,
sizeof(*ws));
1115typedef struct MLDSA_verify_opt_workspace_s {
1117 uint8_t ctilde[64U];
1119 uint8_t ccomp[MLDSA_CCOMP_BYTES];
1120 uint8_t wcomp[MLDSA_WCOMP_BYTES];
1122 uint8_t ctilde2[64U];
1123 uint8_t h_indices[MLDSA_MAX_OMEGA];
1129} MLDSA_verify_opt_workspace_t;
1137 const uint8_t *precomputed_mu,
1142 MLDSA_verify_opt_workspace_t ws_local = {0};
1143 MLDSA_verify_opt_workspace_t *ws = &ws_local;
1145 const uint8_t *sig_z = NULL;
1146 const uint8_t *sig_h = NULL;
1147 uint32_t k_offset = 0U;
1148 cx_err_t error = CX_INTERNAL_ERROR;
1150 if ((sig == NULL) || (pk == NULL)) {
1151 error = CX_INVALID_PARAMETER;
1154 if ((formatted_mprime == NULL) && (precomputed_mu == NULL)) {
1155 error = CX_INVALID_PARAMETER;
1159 error = CX_INVALID_PARAMETER_VALUE;
1165 if (pk_len < p->pk_bytes) {
1166 error = CX_INVALID_PARAMETER_SIZE;
1169 if (sig_len < p->sig_bytes) {
1170 error = CX_INVALID_PARAMETER_SIZE;
1174 explicit_bzero(ws,
sizeof(*ws));
1183 for (uint32_t i = 0U; i < p->
k; i++) {
1184 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
1185 if ((limit < k_offset) || (limit > p->
omega)) {
1186 error = CX_INVALID_PARAMETER;
1189 for (uint32_t j = k_offset; j < limit; j++) {
1190 if ((j > k_offset) && (sig_h[j] <= sig_h[j - 1U])) {
1191 error = CX_INVALID_PARAMETER;
1197 for (uint32_t j = k_offset; j < p->
omega; j++) {
1198 if (sig_h[j] != 0U) {
1199 error = CX_INVALID_PARAMETER;
1205 for (uint8_t j = 0U; j < p->
l; j++) {
1208 error = CX_INVALID_PARAMETER;
1214 if (precomputed_mu != NULL) {
1220 if (error != CX_OK) {
1227 MLDSA_LOWRAM_challenge_compress(ws->ccomp, &ws->tmp, p->
tau);
1231 for (uint8_t i = 0U; i < p->
k; i++) {
1232 uint32_t limit = (uint32_t) sig_h[p->
omega + i];
1235 memset(ws->wcomp, 0, MLDSA_WCOMP_BYTES);
1236 for (uint8_t j = 0U; j < p->
l; j++) {
1237 uint16_t nonce = ((uint16_t) i << 8U) | (uint16_t) j;
1241 MLDSA_LOWRAM_expand_aij_accum(ws->wcomp, &ws->tmp, ws->rho, nonce);
1245 MLDSA_LOWRAM_polyw_unpack(&ws->tmp, ws->wcomp);
1250 MLDSA_LOWRAM_schoolbook_t1(&ws->ct1,
1259 uint32_t num_hints = limit - k_offset;
1260 for (uint32_t j = 0U; j < num_hints; j++) {
1261 ws->h_indices[j] = sig_h[k_offset + j];
1266 MLDSA_LOWRAM_use_hint_indices(&ws->tmp, &ws->tmp, ws->h_indices, num_hints, p->
gamma2);
1279 if (error != CX_OK) {
1284 if (memcmp(ws->ctilde, ws->ctilde2, p->
ctilde_bytes) != 0) {
1285 error = CX_INVALID_PARAMETER;
1292 explicit_bzero(ws,
sizeof(*ws));
1307 cx_err_t error = CX_INTERNAL_ERROR;
1310 if ((pk == NULL) || (sk == NULL)) {
1311 error = CX_INVALID_PARAMETER;
1316 error = CX_INVALID_PARAMETER_VALUE;
1324 explicit_bzero(seed,
sizeof(seed));
1333 size_t *sig_actual_len,
1346 if (error != CX_OK) {
1352 sig, sig_len, sig_actual_len, &mprime, NULL, rnd,
sizeof(rnd), sk, sk_len, param);
1355 explicit_bzero(rnd,
sizeof(rnd));
1375 if (error != CX_OK) {
1387 size_t *sig_actual_len,
1401 if (error != CX_OK) {
1407 sig, sig_len, sig_actual_len, &mprime, NULL, rnd,
sizeof(rnd), sk, sk_len, param);
1410 explicit_bzero(rnd,
sizeof(rnd));
1431 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_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'.
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).
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.
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.
cx_err_t 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::@0 setup_phase
Early-phase temporary used to derive mu.
uint8_t tr[MLDSA_TRBYTES]
struct MLDSA_verify_phase_overlay_t::@1 az_phase
Az product loop temporaries.