Section EQ_MODULO.
Variable modul: Z.
Hypothesis modul_pos: modul > 0.
Definition eqmod (x y: Z) : Prop := exists k, x = k * modul + y.
End EQ_MODULO.
(** ** Fast normalization modulo [2^n] *)
Fixpoint P_mod_two_p (p: positive) (n: nat) {struct n} : Z :=
match n with
| O => 0
| S m =>
match p with
| xH => 1
| xO q => Z.double (P_mod_two_p q m)
| xI q => Z.succ_double (P_mod_two_p q m)
end
end.
Definition Z_mod_two_p (x: Z) (n: nat) : Z :=
match x with
| Z0 => 0
| Zpos p => P_mod_two_p p n
| Zneg p => let r := P_mod_two_p p n in if zeq r 0 then 0 else two_power_nat n - r
end.
(** ** Bit-level operations and properties *)
(** Shift [x] left by one and insert [b] as the low bit of the result. *)
Definition Zshiftin (b: bool) (x: Z) : Z :=
if b then Z.succ_double x else Z.double x.
Remark Ztestbit_0: forall n, Z.testbit 0 n = false.
Proof Z.testbit_0_l.
Remark Ztestbit_1: forall n, Z.testbit 1 n = zeq n 0.
Remark Ztestbit_m1: forall n, 0 <= n -> Z.testbit (-1) n = true.
Remark Zshiftin_spec:
forall b x, Zshiftin b x = 2 * x + (if b then 1 else 0).
Remark Zshiftin_inj:
forall b1 x1 b2 x2,
Zshiftin b1 x1 = Zshiftin b2 x2 -> b1 = b2 /\ x1 = x2.
Remark Zdecomp:
forall x, x = Zshiftin (Z.odd x) (Z.div2 x).
Remark Ztestbit_shiftin:
forall b x n,
0 <= n ->
Z.testbit (Zshiftin b x) n = if zeq n 0 then b else Z.testbit x (Z.pred n).
Remark Ztestbit_shiftin_base:
forall b x, Z.testbit (Zshiftin b x) 0 = b.
Remark Ztestbit_shiftin_succ:
forall b x n, 0 <= n -> Z.testbit (Zshiftin b x) (Z.succ n) = Z.testbit x n.
(** ** Bit-wise decomposition ([Z.testbit]) *)
Remark Ztestbit_eq:
forall n x, 0 <= n ->
Z.testbit x n = if zeq n 0 then Z.odd x else Z.testbit (Z.div2 x) (Z.pred n).
Remark Ztestbit_base:
forall x, Z.testbit x 0 = Z.odd x.
Remark Ztestbit_succ:
forall n x, 0 <= n -> Z.testbit x (Z.succ n) = Z.testbit (Z.div2 x) n.

Lemma eqmod_same_bits:
forall n x y,
(forall i, 0 <= i < Z.of_nat n -> Z.testbit x i = Z.testbit y i) ->
eqmod (two_power_nat n) x y.