rewrite r'_i_eq. fold x''. rewrite Z_div_mod_eq with (a := x'' mod 2 ^ p) (b := M).
rewrite Zplus_comm with (m := (x'' mod 2 ^ p) mod M). rewrite Zplus_assoc.
rewrite Z_div_mod_eq with (a := (x'' / 2 ^ p * 2 ^ p) mod M + (x'' mod 2 ^ p) mod M) (b := M). rewrite <- Zmod_plus_distr_l.
rewrite Zplus_comm with (n := x'' / 2 ^ p * 2 ^ p). rewrite <- Zmod_plus_distr_l. rewrite Zplus_comm with (n := x'' mod 2 ^ p).
rewrite Zmult_comm with (m := 2 ^ p). rewrite <- Z_div_mod_eq. replace (x'' mod M) with (x mod M).
elim (sum_r'_i (2 ^ p * (x'' / 2 ^ p)) (x'' mod 2 ^ p)); intro H; elim (div_r'_i x''); intro H0; rewrite H; rewrite H0. left. ring.
right. left. ring. right. left. ring. right. right. ring. unfold x''. rewrite Zmod_plus_distr_l. rewrite <- Zmod_mult_distr_l.
rewrite <- Zmod_plus_distr_l. trivial. omega. omega. omega. apply Zlt_gt. apply lt_0_Zpow. auto with a. omega. omega. omega.
omega. Qed.

(* <KE EP TOGETHER - s_i_eq *)
Lemma s_i_eq : _Z s_i = x' mod 2 ^ w / 2 ^ p.
simpl. fold l. fold p. fold x_i. rewrite x_i_eq. trivial. Qed.