#include "gfp_internal.h"
#include <openssl/type_check.h>
#include "../internal.h"
#include "gfp_limbs.inl"
GFp_Limb GFp_constant_time_limbs_lt_limbs(const GFp_Limb a[],
const GFp_Limb b[],
size_t num_limbs);
OPENSSL_COMPILE_ASSERT(sizeof(size_t) == sizeof(GFp_Limb),
size_t_and_gfp_limb_are_different_sizes);
GFp_Limb GFp_constant_time_limbs_are_zero(const GFp_Limb a[],
size_t num_limbs) {
assert(num_limbs >= 1);
GFp_Limb is_zero = constant_time_is_zero_size_t(a[0]);
for (size_t i = 1; i < num_limbs; ++i) {
is_zero = constant_time_select_size_t(
is_zero, constant_time_is_zero_size_t(a[i]), is_zero);
}
return is_zero;
}
GFp_Limb GFp_constant_time_limbs_eq_limbs(const GFp_Limb a[],
const GFp_Limb b[],
size_t num_limbs) {
assert(num_limbs >= 1);
GFp_Limb eq = constant_time_eq_size_t(a[0], b[0]);
for (size_t i = 1; i < num_limbs; ++i) {
eq = constant_time_select_size_t(eq, constant_time_eq_size_t(a[i], b[i]),
eq);
}
return eq;
}
GFp_Limb GFp_constant_time_limbs_lt_limbs(const GFp_Limb a[],
const GFp_Limb b[],
size_t num_limbs) {
assert(num_limbs >= 1);
GFp_Limb dummy;
GFp_Carry borrow = gfp_sub(&dummy, a[0], b[0]);
for (size_t i = 1; i < num_limbs; ++i) {
borrow = gfp_sbb(&dummy, a[i], b[i], borrow);
}
return constant_time_is_nonzero_size_t(borrow);
}
void GFp_constant_time_limbs_reduce_once(GFp_Limb r[], const GFp_Limb m[],
size_t num_limbs) {
assert(num_limbs >= 1);
GFp_Limb lt = GFp_constant_time_limbs_lt_limbs(r, m, num_limbs);
GFp_Carry borrow = gfp_sub(&r[0], r[0],
constant_time_select_size_t(lt, 0, m[0]));
for (size_t i = 1; i < num_limbs; ++i) {
borrow = gfp_sbb(&r[i], r[i],
constant_time_select_size_t(lt, 0, m[i]), borrow);
}
assert(borrow == 0);
}