///| a = a0 + a1 * 2 ^ D
pub fn power2round(a : Int) -> (Int, Int) {
let a1 = (a + (1 << (D - 1)) - 1) >> D
let a0 = a - (a1 << D)
(a0, a1)
}
///| a = a0 + a1 * 2 * gamma2
/// gamma2 = (Q - 1) / 32 or (Q - 1) / 88
///
pub fn decompose(a : Int) -> (Int, Int) {
let gamma2 = dilithium_context.get_params_set().gamma2
let mut a1 = (a + 127) >> 7
let mut a0 = a
// Q = 1023 * 2 ^ {13} + 1
if gamma2 == (Q - 1) / 32 { // gamma2 = 2556413 = 1023 * 2 ^ {8} < 2 ^ {13}
a1 = (a1 * 1025 + (1 << 21)) >> 22
a1 = a1 & 15
} else if gamma2 == (Q - 1) / 88 {
a1 = (a1 * 11275 + (1 << 23)) >> 24
a1 = a1 ^ (((43 - a1) >> 31) & a1)
}
a0 = a - a1 * 2 * gamma2
a0 = a0 - ((((Q - 1) / 2 - a0) >> 31) & Q)
(a0, a1)
}
///|
pub fn make_hint(a0 : Int, a1 : Int) -> Byte {
let gamma2 = dilithium_context.get_params_set().gamma2
let result = (a0 > gamma2).to_int() |
(a0 < -gamma2).to_int() |
((a0 == -gamma2).to_int() & (a1 != 0).to_int())
result.to_byte()
}
///|
pub fn use_hint(a : Int, hint : Byte) -> Int {
let (a0, a1) = decompose(a)
let gamma2 = dilithium_context.get_params_set().gamma2
// 使用ite避免分支,实现常时间执行
// Use ite to avoid branching for constant-time execution
// 判断是否为特殊的gamma2值 (Q-1)/32
// Check if gamma2 is the special value (Q-1)/32
let is_special_gamma2 = gamma2 == (Q - 1) / 32
// 对于特殊gamma2值的处理
// Handling for special gamma2 value
let special_result = ite(
a0 > 0,
(a1 + 1) & 15, // a0 > 0 的情况
(a1 - 1) & 15, // a0 <= 0 的情况
)
// 对于普通gamma2值的处理
// Handling for normal gamma2 value
let normal_result_positive = ite(
a1 == 43,
0, // a1 == 43 的情况
a1 + 1, // a1 != 43 的情况
)
let normal_result_negative = ite(
a1 == 0,
43, // a1 == 0 的情况
a1 - 1, // a1 != 0 的情况
)
let normal_result = ite(
a0 > 0,
normal_result_positive,
normal_result_negative,
)
// 在特殊gamma2和普通gamma2之间选择
// Choose between special and normal gamma2 handling
let computed_result = ite(is_special_gamma2, special_result, normal_result)
// 最终根据hint值决定是否使用计算结果
// Finally decide whether to use computed result based on hint value
let result = ite(
hint == 0,
a1, // hint == 0: 使用原始a1值
computed_result, // hint != 0: 使用计算后的结果
)
result
}