//! Constructor for [`Divstep`] state.
use super::Divstep;
use crate::u256::U256;

impl Divstep {
    /// Initializes the divstep state for computing the modular inverse
    /// of `value` modulo `modulus`.
    ///
    /// Sets `f = modulus` (positive), `g = value` (positive), `delta = 1`,
    /// `d = 0`, `e = 1`. The invariant `d * modulus + e * value ≡ g` holds
    /// at initialization and is maintained through all divstep transitions.
    pub(crate) fn new(modulus: U256, value: U256) -> Divstep {
        Divstep {
            delta: 1,
            f: modulus,
            f_neg: false,
            g: value,
            g_neg: false,
            d: U256::ZERO,
            e: U256::ONE,
            modulus,
        }
    }
}

#[cfg(test)]
mod ai_tests {
    use super::*;

    const P: U256 = U256::from_be_limbs([
        0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
        0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFC2F,
    ]);

    /// Initial state has expected field values.
    #[test]
    fn initial_state() {
        let ds = Divstep::new(P, U256::from_be_limbs([0, 0, 0, 7]));
        assert_eq!(ds.delta, 1);
        assert_eq!(ds.f, P);
        assert!(!ds.f_neg);
        assert_eq!(ds.g, U256::from_be_limbs([0, 0, 0, 7]));
        assert!(!ds.g_neg);
        assert_eq!(ds.d, U256::ZERO);
        assert_eq!(ds.e, U256::ONE);
        assert_eq!(ds.modulus, P);
    }
}
