#ifndef MLD_REDUCE_H
#define MLD_REDUCE_H
#include "cbmc.h"
#include "common.h"
#include "ct.h"
#include "debug.h"
#define MLD_MONT (-4186625)
#define MLD_REDUCE32_DOMAIN_MAX (INT32_MAX - ((int32_t)1 << 22))
#define MLD_REDUCE32_RANGE_MAX 6283009
MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int32_t mld_montgomery_reduce(int64_t a)
__contract__(
requires(a > -(((int64_t)1 << 31) * MLDSA_Q) &&
a < (((int64_t)1 << 31) * MLDSA_Q))
ensures(return_value > -MLDSA_Q && return_value < MLDSA_Q)
)
{
const uint64_t QINV = 58728449;
const uint32_t a_reduced = mld_cast_int64_to_uint32(a);
const uint32_t a_inverted = (a_reduced * QINV) & UINT32_MAX;
const int32_t t = mld_cast_uint32_to_int32(a_inverted);
int64_t r;
mld_assert(a < +(INT64_MAX - (((int64_t)1 << 31) * MLDSA_Q)) &&
a > -(INT64_MAX - (((int64_t)1 << 31) * MLDSA_Q)));
r = a - (int64_t)t * MLDSA_Q;
r = r >> 32;
return (int32_t)r;
}
MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int32_t mld_reduce32(int32_t a)
__contract__(
requires(a <= MLD_REDUCE32_DOMAIN_MAX)
ensures(return_value >= -MLD_REDUCE32_RANGE_MAX)
ensures(return_value < MLD_REDUCE32_RANGE_MAX)
)
{
int32_t t;
t = (a + ((int32_t)1 << 22)) >> 23;
t = a - t * MLDSA_Q;
mld_assert((t - a) % MLDSA_Q == 0);
return t;
}
MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int32_t mld_caddq(int32_t a)
__contract__(
requires(a > -MLDSA_Q)
requires(a < MLDSA_Q)
ensures(return_value >= 0)
ensures(return_value < MLDSA_Q)
ensures(return_value == ((a >= 0) ? a : (a + MLDSA_Q)))
)
{
return mld_ct_sel_int32(a + MLDSA_Q, a, mld_ct_cmask_neg_i32(a));
}
#endif