use super::Divstep;
use crate::divstep_matrix::DivstepMatrix;
impl Divstep {
pub(crate) fn macrostep(&mut self) {
let mut f0 = self.extract_low62_signed(&self.f, self.f_neg);
let mut g0 = self.extract_low62_signed(&self.g, self.g_neg);
let mut matrix = DivstepMatrix::identity();
for _ in 0..62 {
self.delta = matrix.step(self.delta, &mut f0, &mut g0);
}
let (new_f, new_f_neg, new_g, new_g_neg) =
matrix.apply_fg(&self.f, self.f_neg, &self.g, self.g_neg);
self.f = new_f;
self.f_neg = new_f_neg;
self.g = new_g;
self.g_neg = new_g_neg;
let (new_d, new_e) = matrix.apply_de(&self.d, &self.e, &self.modulus);
self.d = new_d;
self.e = new_e;
}
fn extract_low62_signed(&self, val: &crate::u256::U256, neg: bool) -> i64 {
let low62 = (val.0[0] & ((1u64 << 62) - 1)) as i64;
if neg { -low62 } else { low62 }
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
use crate::u256::U256;
const P: U256 = U256::from_be_limbs([
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFC2F,
]);
#[test]
fn one_macrostep_no_panic() {
let mut ds = Divstep::new(P, U256::from_be_limbs([0, 0, 0, 7]));
ds.macrostep();
}
#[test]
fn bezout_coefficients_reduced() {
let mut ds = Divstep::new(P, U256::from_be_limbs([0, 0, 0, 7]));
ds.macrostep();
assert!(ds.d < P);
assert!(ds.e < P);
}
}