#ifndef MLD_POLYVEC_LAZY_H
#define MLD_POLYVEC_LAZY_H
#if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API) || \
!defined(MLD_CONFIG_NO_VERIFY_API)
#include "poly.h"
#include "poly_kl.h"
#include "polyvec.h"
#define mld_sk_s1hat_eager MLD_ADD_PARAM_SET(mld_sk_s1hat_eager)
#define mld_sk_s1hat_lazy MLD_ADD_PARAM_SET(mld_sk_s1hat_lazy)
#define mld_sk_s1hat MLD_ADD_PARAM_SET(mld_sk_s1hat)
#define mld_unpack_sk_s1hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_s1hat_eager)
#define mld_unpack_sk_s1hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_s1hat_lazy)
#define mld_sk_s1hat_get_poly_eager \
MLD_ADD_PARAM_SET(mld_sk_s1hat_get_poly_eager)
#define mld_sk_s1hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_s1hat_get_poly_lazy)
#define mld_sk_s2hat_eager MLD_ADD_PARAM_SET(mld_sk_s2hat_eager)
#define mld_sk_s2hat_lazy MLD_ADD_PARAM_SET(mld_sk_s2hat_lazy)
#define mld_sk_s2hat MLD_ADD_PARAM_SET(mld_sk_s2hat)
#define mld_unpack_sk_s2hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_s2hat_eager)
#define mld_unpack_sk_s2hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_s2hat_lazy)
#define mld_sk_s2hat_get_poly_eager \
MLD_ADD_PARAM_SET(mld_sk_s2hat_get_poly_eager)
#define mld_sk_s2hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_s2hat_get_poly_lazy)
#define mld_sk_t0hat_eager MLD_ADD_PARAM_SET(mld_sk_t0hat_eager)
#define mld_sk_t0hat_lazy MLD_ADD_PARAM_SET(mld_sk_t0hat_lazy)
#define mld_sk_t0hat MLD_ADD_PARAM_SET(mld_sk_t0hat)
#define mld_unpack_sk_t0hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_t0hat_eager)
#define mld_unpack_sk_t0hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_t0hat_lazy)
#define mld_sk_t0hat_get_poly_eager \
MLD_ADD_PARAM_SET(mld_sk_t0hat_get_poly_eager)
#define mld_sk_t0hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_t0hat_get_poly_lazy)
#define mld_polymat MLD_ADD_PARAM_SET(mld_polymat)
#define mld_polymat_eager MLD_ADD_PARAM_SET(mld_polymat_eager)
#define mld_polymat_lazy MLD_ADD_PARAM_SET(mld_polymat_lazy)
#define mld_poly_permute_bitrev_to_custom_optional \
MLD_ADD_PARAM_SET(mld_poly_permute_bitrev_to_custom_optional)
#define mld_polyvec_matrix_expand_eager \
MLD_NAMESPACE_KL(polyvec_matrix_expand_eager)
#define mld_polyvec_matrix_expand_lazy \
MLD_NAMESPACE_KL(polyvec_matrix_expand_lazy)
#define mld_polyvec_matrix_pointwise_montgomery \
MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery)
#define mld_polyvec_matrix_pointwise_montgomery_row_eager \
MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_row_eager)
#define mld_polyvec_matrix_pointwise_montgomery_row_lazy \
MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_row_lazy)
#define mld_polyvec_matrix_pointwise_montgomery_yvec_eager \
MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_yvec_eager)
#define mld_polyvec_matrix_pointwise_montgomery_yvec_lazy \
MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_yvec_lazy)
#define mld_yvec_eager MLD_ADD_PARAM_SET(mld_yvec_eager)
#define mld_yvec_lazy MLD_ADD_PARAM_SET(mld_yvec_lazy)
#define mld_yvec MLD_ADD_PARAM_SET(mld_yvec)
#define mld_yvec_init_eager MLD_ADD_PARAM_SET(mld_yvec_init_eager)
#define mld_yvec_init_lazy MLD_ADD_PARAM_SET(mld_yvec_init_lazy)
#define mld_yvec_get_poly_eager MLD_ADD_PARAM_SET(mld_yvec_get_poly_eager)
#define mld_yvec_get_poly_lazy MLD_ADD_PARAM_SET(mld_yvec_get_poly_lazy)
typedef struct
{
mld_polyvecl vec;
} mld_sk_s1hat_eager;
typedef struct
{
mld_polyveck vec;
} mld_sk_s2hat_eager;
typedef struct
{
mld_polyveck vec;
} mld_sk_t0hat_eager;
typedef struct
{
const uint8_t *packed;
} mld_sk_s1hat_lazy;
typedef struct
{
const uint8_t *packed;
} mld_sk_s2hat_lazy;
typedef struct
{
const uint8_t *packed;
} mld_sk_t0hat_lazy;
typedef struct
{
mld_polyvecl vec;
} mld_yvec_eager;
typedef struct
{
const uint8_t *rhoprime;
uint16_t kappa;
} mld_yvec_lazy;
#if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API)
#if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
static MLD_INLINE void mld_unpack_sk_s1hat_eager(
mld_sk_s1hat_eager *s1,
const uint8_t packed_s1[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES])
__contract__(
requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_eager)))
requires(memory_no_alias(packed_s1, MLDSA_L * MLDSA_POLYETA_PACKEDBYTES))
assigns(memory_slice(s1, sizeof(mld_sk_s1hat_eager)))
ensures(forall(k1, 0, MLDSA_L,
array_abs_bound(s1->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
)
{
mld_polyvecl_unpack_eta(&s1->vec, packed_s1);
mld_polyvecl_ntt(&s1->vec);
}
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_s1hat_get_poly_eager(mld_poly *buf,
const mld_sk_s1hat_eager *s1,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_eager)))
requires(i < MLDSA_L)
requires(array_abs_bound(s1->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
) { *buf = s1->vec.vec[i]; }
#endif
#endif
#if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
static MLD_INLINE void mld_unpack_sk_s1hat_lazy(
mld_sk_s1hat_lazy *s1,
const uint8_t packed_s1[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES])
__contract__(
requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_lazy)))
assigns(memory_slice(s1, sizeof(mld_sk_s1hat_lazy)))
ensures(s1->packed == old(packed_s1))
) { s1->packed = packed_s1; }
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_s1hat_get_poly_lazy(mld_poly *buf,
const mld_sk_s1hat_lazy *s1,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_lazy)))
requires(i < MLDSA_L)
requires(memory_no_alias(s1->packed, MLDSA_L * MLDSA_POLYETA_PACKEDBYTES))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
)
{
mld_polyeta_unpack(buf, s1->packed + i * MLDSA_POLYETA_PACKEDBYTES);
mld_poly_ntt(buf);
}
#endif
#endif
#if (!defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)) && \
(!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
static MLD_INLINE void mld_unpack_sk_s2hat_eager(
mld_sk_s2hat_eager *s2,
const uint8_t packed_s2[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES])
__contract__(
requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_eager)))
requires(memory_no_alias(packed_s2, MLDSA_K * MLDSA_POLYETA_PACKEDBYTES))
assigns(memory_slice(s2, sizeof(mld_sk_s2hat_eager)))
ensures(forall(k1, 0, MLDSA_K,
array_abs_bound(s2->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
)
{
mld_polyveck_unpack_eta(&s2->vec, packed_s2);
mld_polyveck_ntt(&s2->vec);
}
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_s2hat_get_poly_eager(mld_poly *buf,
const mld_sk_s2hat_eager *s2,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_eager)))
requires(i < MLDSA_K)
requires(array_abs_bound(s2->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
) { *buf = s2->vec.vec[i]; }
#endif
#endif
#if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
static MLD_INLINE void mld_unpack_sk_s2hat_lazy(
mld_sk_s2hat_lazy *s2,
const uint8_t packed_s2[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES])
__contract__(
requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_lazy)))
assigns(memory_slice(s2, sizeof(mld_sk_s2hat_lazy)))
ensures(s2->packed == old(packed_s2))
) { s2->packed = packed_s2; }
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_s2hat_get_poly_lazy(mld_poly *buf,
const mld_sk_s2hat_lazy *s2,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_lazy)))
requires(i < MLDSA_K)
requires(memory_no_alias(s2->packed, MLDSA_K * MLDSA_POLYETA_PACKEDBYTES))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
)
{
mld_polyeta_unpack(buf, s2->packed + i * MLDSA_POLYETA_PACKEDBYTES);
mld_poly_ntt(buf);
}
#endif
#endif
#if (!defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)) && \
(!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
static MLD_INLINE void mld_unpack_sk_t0hat_eager(
mld_sk_t0hat_eager *t0,
const uint8_t packed_t0[MLDSA_K * MLDSA_POLYT0_PACKEDBYTES])
__contract__(
requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_eager)))
requires(memory_no_alias(packed_t0, MLDSA_K * MLDSA_POLYT0_PACKEDBYTES))
assigns(memory_slice(t0, sizeof(mld_sk_t0hat_eager)))
ensures(forall(k1, 0, MLDSA_K,
array_abs_bound(t0->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
)
{
unsigned int i;
for (i = 0; i < MLDSA_K; ++i)
__loop__(
assigns(i, memory_slice(t0, sizeof(mld_sk_t0hat_eager)))
invariant(i <= MLDSA_K)
invariant(forall(k0, 0, i,
array_bound(t0->vec.vec[k0].coeffs, 0, MLDSA_N,
-(1 << (MLDSA_D - 1)) + 1, (1 << (MLDSA_D - 1)) + 1)))
decreases(MLDSA_K - i)
)
{
mld_polyt0_unpack(&t0->vec.vec[i],
packed_t0 + i * MLDSA_POLYT0_PACKEDBYTES);
}
mld_polyveck_ntt(&t0->vec);
}
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_t0hat_get_poly_eager(mld_poly *buf,
const mld_sk_t0hat_eager *t0,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_eager)))
requires(i < MLDSA_K)
requires(array_abs_bound(t0->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
) { *buf = t0->vec.vec[i]; }
#endif
#endif
#if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
static MLD_INLINE void mld_unpack_sk_t0hat_lazy(
mld_sk_t0hat_lazy *t0,
const uint8_t packed_t0[MLDSA_K * MLDSA_POLYT0_PACKEDBYTES])
__contract__(
requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_lazy)))
assigns(memory_slice(t0, sizeof(mld_sk_t0hat_lazy)))
ensures(t0->packed == old(packed_t0))
) { t0->packed = packed_t0; }
#if !defined(MLD_CONFIG_NO_SIGN_API)
static MLD_INLINE void mld_sk_t0hat_get_poly_lazy(mld_poly *buf,
const mld_sk_t0hat_lazy *t0,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_lazy)))
requires(i < MLDSA_K)
requires(memory_no_alias(t0->packed, MLDSA_K * MLDSA_POLYT0_PACKEDBYTES))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
)
{
mld_polyt0_unpack(buf, t0->packed + i * MLDSA_POLYT0_PACKEDBYTES);
mld_poly_ntt(buf);
}
#endif
#endif
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API) && \
(!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
static MLD_INLINE void mld_yvec_init_eager(
mld_yvec_eager *y, const uint8_t rhoprime[MLDSA_CRHBYTES], uint16_t kappa)
__contract__(
requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
requires(memory_no_alias(rhoprime, MLDSA_CRHBYTES))
requires(kappa <= UINT16_MAX - MLDSA_L)
assigns(memory_slice(y, sizeof(mld_yvec_eager)))
ensures(forall(k1, 0, MLDSA_L,
array_bound(y->vec.vec[k1].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
)
{
mld_polyvecl_uniform_gamma1(&y->vec, rhoprime, kappa);
}
static MLD_INLINE void mld_yvec_get_poly_eager(mld_poly *buf,
const mld_yvec_eager *y,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
requires(i < MLDSA_L)
requires(array_bound(y->vec.vec[i].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_bound(buf->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
) { *buf = y->vec.vec[i]; }
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API) && \
(defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
static MLD_INLINE void mld_yvec_init_lazy(
mld_yvec_lazy *y, const uint8_t rhoprime[MLDSA_CRHBYTES], uint16_t kappa)
__contract__(
requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
assigns(memory_slice(y, sizeof(mld_yvec_lazy)))
ensures(y->rhoprime == old(rhoprime))
ensures(y->kappa == old(kappa))
)
{
y->rhoprime = rhoprime;
y->kappa = kappa;
}
static MLD_INLINE void mld_yvec_get_poly_lazy(mld_poly *buf,
const mld_yvec_lazy *y,
unsigned int i)
__contract__(
requires(memory_no_alias(buf, sizeof(mld_poly)))
requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
requires(i < MLDSA_L)
requires(memory_no_alias(y->rhoprime, MLDSA_CRHBYTES))
requires(y->kappa <= UINT16_MAX - MLDSA_L)
assigns(memory_slice(buf, sizeof(mld_poly)))
ensures(array_bound(buf->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
)
{
mld_poly_uniform_gamma1(buf, y->rhoprime, (uint16_t)(y->kappa + i));
}
#endif
#if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
typedef struct
{
mld_polyvecl vec[MLDSA_K];
} mld_polymat_eager;
#endif
typedef struct
{
mld_poly cur;
uint8_t rho[MLDSA_SEEDBYTES];
} mld_polymat_lazy;
static MLD_INLINE void mld_poly_permute_bitrev_to_custom_optional(mld_poly *p)
__contract__(
requires(memory_no_alias(p, sizeof(mld_poly)))
requires(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
assigns(memory_slice(p, sizeof(mld_poly)))
ensures(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
)
{
#if defined(MLD_USE_NATIVE_NTT_CUSTOM_ORDER)
mld_poly_permute_bitrev_to_custom(p->coeffs);
#else
(void)p;
#endif
}
#if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
MLD_INTERNAL_API
void mld_polyvec_matrix_expand_eager(mld_polymat_eager *mat,
const uint8_t rho[MLDSA_SEEDBYTES])
__contract__(
requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
assigns(memory_slice(mat, sizeof(mld_polymat_eager)))
ensures(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
);
MLD_INTERNAL_API
void mld_polyvec_matrix_pointwise_montgomery_row_eager(mld_poly *t_row,
mld_polymat_eager *mat,
const mld_polyvecl *v,
unsigned int i)
__contract__(
requires(memory_no_alias(t_row, sizeof(mld_poly)))
requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
requires(memory_no_alias(v, sizeof(mld_polyvecl)))
requires(i < MLDSA_K)
requires(forall(l1, 0, MLDSA_L,
array_bound(mat->vec[i].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
requires(forall(l2, 0, MLDSA_L,
array_abs_bound(v->vec[l2].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
assigns(memory_slice(t_row, sizeof(mld_poly)))
ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
);
#if !defined(MLD_CONFIG_NO_SIGN_API)
MLD_INTERNAL_API
void mld_polyvec_matrix_pointwise_montgomery_yvec_eager(mld_polyveck *w,
mld_polymat_eager *mat,
const mld_yvec_eager *y,
mld_polyvecl *scratch)
__contract__(
requires(memory_no_alias(w, sizeof(mld_polyveck)))
requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
requires(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
requires(forall(l2, 0, MLDSA_L,
array_bound(y->vec.vec[l2].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
assigns(memory_slice(w, sizeof(mld_polyveck)))
assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
ensures(forall(k0, 0, MLDSA_K,
array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
);
#endif
#endif
#if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
MLD_INTERNAL_API
void mld_polyvec_matrix_expand_lazy(mld_polymat_lazy *mat,
const uint8_t rho[MLDSA_SEEDBYTES])
__contract__(
requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
);
#if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
MLD_INTERNAL_API
void mld_polyvec_matrix_pointwise_montgomery_row_lazy(mld_poly *t_row,
mld_polymat_lazy *mat,
const mld_polyvecl *v,
unsigned int i)
__contract__(
requires(memory_no_alias(t_row, sizeof(mld_poly)))
requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
requires(memory_no_alias(v, sizeof(mld_polyvecl)))
requires(i < MLDSA_K)
requires(forall(l1, 0, MLDSA_L,
array_abs_bound(v->vec[l1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
assigns(memory_slice(t_row, sizeof(mld_poly)))
assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
);
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API)
MLD_INTERNAL_API
void mld_polyvec_matrix_pointwise_montgomery_yvec_lazy(mld_polyveck *w,
mld_polymat_lazy *mat,
const mld_yvec_lazy *y,
mld_polyvecl *scratch)
__contract__(
requires(memory_no_alias(w, sizeof(mld_polyveck)))
requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
requires(memory_no_alias(y->rhoprime, MLDSA_CRHBYTES))
requires(y->kappa <= UINT16_MAX - MLDSA_L)
assigns(memory_slice(w, sizeof(mld_polyveck)))
assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
ensures(forall(k0, 0, MLDSA_K,
array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
);
#endif
#endif
#if defined(MLD_CONFIG_REDUCE_RAM)
typedef mld_sk_s1hat_lazy mld_sk_s1hat;
typedef mld_sk_s2hat_lazy mld_sk_s2hat;
typedef mld_sk_t0hat_lazy mld_sk_t0hat;
typedef mld_polymat_lazy mld_polymat;
typedef mld_yvec_lazy mld_yvec;
#define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_lazy
#define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_lazy
#define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_lazy
#if !defined(MLD_CONFIG_NO_SIGN_API)
#define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_lazy
#define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_lazy
#define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_lazy
#endif
#define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_lazy
#define mld_polyvec_matrix_pointwise_montgomery_row \
mld_polyvec_matrix_pointwise_montgomery_row_lazy
#define mld_yvec_init mld_yvec_init_lazy
#define mld_yvec_get_poly mld_yvec_get_poly_lazy
#define mld_polyvec_matrix_pointwise_montgomery_yvec \
mld_polyvec_matrix_pointwise_montgomery_yvec_lazy
#else
typedef mld_sk_s1hat_eager mld_sk_s1hat;
typedef mld_sk_s2hat_eager mld_sk_s2hat;
typedef mld_sk_t0hat_eager mld_sk_t0hat;
typedef mld_polymat_eager mld_polymat;
typedef mld_yvec_eager mld_yvec;
#define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_eager
#define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_eager
#define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_eager
#if !defined(MLD_CONFIG_NO_SIGN_API)
#define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_eager
#define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_eager
#define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_eager
#endif
#define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_eager
#define mld_polyvec_matrix_pointwise_montgomery_row \
mld_polyvec_matrix_pointwise_montgomery_row_eager
#define mld_yvec_init mld_yvec_init_eager
#define mld_yvec_get_poly mld_yvec_get_poly_eager
#define mld_polyvec_matrix_pointwise_montgomery_yvec \
mld_polyvec_matrix_pointwise_montgomery_yvec_eager
#endif
#endif
#endif