aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_CoqProject4
-rw-r--r--src/ModularArithmetic/ModularBaseSystem.v126
-rw-r--r--src/ModularArithmetic/ModularBaseSystemField.v71
-rw-r--r--src/ModularArithmetic/ModularBaseSystemInterface.v150
-rw-r--r--src/ModularArithmetic/ModularBaseSystemList.v69
-rw-r--r--src/ModularArithmetic/ModularBaseSystemListProofs.v95
-rw-r--r--src/ModularArithmetic/ModularBaseSystemOpt.v142
-rw-r--r--src/ModularArithmetic/ModularBaseSystemProofs.v507
-rw-r--r--src/ModularArithmetic/Pow2Base.v1
-rw-r--r--src/ModularArithmetic/Pow2BaseProofs.v22
-rw-r--r--src/Specific/GF1305.v60
-rw-r--r--src/Specific/GF25519.v59
12 files changed, 622 insertions, 684 deletions
diff --git a/_CoqProject b/_CoqProject
index 404178d8a..187ea6541 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -38,7 +38,9 @@ src/ModularArithmetic/ExtPow2BaseMulProofs.v
src/ModularArithmetic/ExtendedBaseVector.v
src/ModularArithmetic/ModularArithmeticTheorems.v
src/ModularArithmetic/ModularBaseSystem.v
-src/ModularArithmetic/ModularBaseSystemInterface.v
+src/ModularArithmetic/ModularBaseSystemField.v
+src/ModularArithmetic/ModularBaseSystemList.v
+src/ModularArithmetic/ModularBaseSystemListProofs.v
src/ModularArithmetic/ModularBaseSystemOpt.v
src/ModularArithmetic/ModularBaseSystemProofs.v
src/ModularArithmetic/Pow2Base.v
diff --git a/src/ModularArithmetic/ModularBaseSystem.v b/src/ModularArithmetic/ModularBaseSystem.v
index 8c850c941..70c8138da 100644
--- a/src/ModularArithmetic/ModularBaseSystem.v
+++ b/src/ModularArithmetic/ModularBaseSystem.v
@@ -1,103 +1,79 @@
Require Import Coq.ZArith.Zpower Coq.ZArith.ZArith.
Require Import Coq.Lists.List.
-Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil.
Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
Require Import Crypto.BaseSystem.
-Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
+Require Import Crypto.BaseSystemProofs.
Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
-Require Import Crypto.Tactics.VerdiTactics.
-Require Import Crypto.Util.Notations.
Require Import Crypto.ModularArithmetic.Pow2Base.
+Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemList.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemListProofs.
+Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil.
+Require Import Crypto.Util.Tuple.
+Require Import Crypto.Util.Notations.
+Require Import Crypto.Tactics.VerdiTactics.
Local Open Scope Z_scope.
-Section PseudoMersenneBase.
- Context `{prm :PseudoMersenneBaseParams} (modulus_multiple : digits).
+Section ModularBaseSystem.
+ Context `{prm :PseudoMersenneBaseParams}.
Local Notation base := (base_from_limb_widths limb_widths).
+ Local Notation digits := (tuple Z (length limb_widths)).
+ Local Arguments to_list {_ _} _.
+ Local Arguments from_list {_ _} _ _.
+ Local Arguments length_to_list {_ _ _}.
+ Local Notation "[[ u ]]" := (to_list u).
- Definition decode (us : digits) : F modulus := ZToField (BaseSystem.decode base us).
-
- Definition rep (us : digits) (x : F modulus) := (length us = length base)%nat /\ decode us = x.
- Local Notation "u ~= x" := (rep u x).
- Local Hint Unfold rep.
-
- (* max must be greater than input; this is used to truncate last digit *)
- Definition encode (x : F modulus) := encodeZ limb_widths x.
-
- (* Converts from length of extended base to length of base by reduction modulo M.*)
- Definition reduce (us : digits) : digits :=
- let high := skipn (length base) us in
- let low := firstn (length base) us in
- let wrap := map (Z.mul c) high in
- BaseSystem.add low wrap.
-
- Definition mul (us vs : digits) := reduce (BaseSystem.mul (ext_base limb_widths) us vs).
+ Definition decode (us : digits) : F modulus := decode [[us]].
- (* In order to subtract without underflowing, we add a multiple of the modulus first. *)
- Definition sub (us vs : digits) := BaseSystem.sub (add modulus_multiple us) vs.
+ Definition encode (x : F modulus) : digits := from_list (encode x) length_encode.
-End PseudoMersenneBase.
-
-Section CarryBasePow2.
- Context `{prm :PseudoMersenneBaseParams}.
- Local Notation base := (base_from_limb_widths limb_widths).
- Local Notation log_cap i := (nth_default 0 limb_widths i).
+ Definition add (us vs : digits) : digits := from_list (add [[us]] [[vs]])
+ (add_same_length _ _ _ length_to_list length_to_list).
- (*
- Definition carry_and_reduce :=
- carry_gen limb_widths (fun ci => c * ci).
- *)
- Definition carry_and_reduce i := fun us =>
- let di := nth_default 0 us i in
- let us' := set_nth i (Z.pow2_mod di (log_cap i)) us in
- add_to_nth 0 (c * (Z.shiftr di (log_cap i))) us'.
+ Definition mul (us vs : digits) : digits := from_list (mul [[us]] [[vs]])
+ (length_mul length_to_list length_to_list).
- Definition carry i : digits -> digits :=
- if eq_nat_dec i (pred (length base))
- then carry_and_reduce i
- else carry_simple limb_widths i.
+ Definition sub (modulus_multiple us vs : digits) : digits :=
+ from_list (sub [[modulus_multiple]] [[us]] [[vs]])
+ (length_sub length_to_list length_to_list length_to_list).
- Definition carry_sequence is us := fold_right carry us is.
+ Definition zero : digits := encode (ZToField 0).
- Definition carry_full := carry_sequence (full_carry_chain limb_widths).
+ Definition one : digits := encode (ZToField 1).
- Definition carry_mul us vs := carry_full (mul us vs).
+ (* Placeholder *)
+ Definition opp (x : digits) : digits := encode (ModularArithmetic.opp (decode x)).
-End CarryBasePow2.
+ (* Placeholder *)
+ Definition inv (x : digits) : digits := encode (ModularArithmetic.inv (decode x)).
-Section Canonicalization.
- Context `{prm :PseudoMersenneBaseParams}.
- Local Notation base := (base_from_limb_widths limb_widths).
- Local Notation log_cap i := (nth_default 0 limb_widths i).
+ (* Placeholder *)
+ Definition div (x y : digits) : digits := encode (ModularArithmetic.div (decode x) (decode y)).
- (* compute at compile time *)
- Definition max_ones := Z.ones (fold_right Z.max 0 limb_widths).
+ Definition carry i (us : digits) : digits := from_list (carry i [[us]])
+ (length_carry length_to_list).
- Definition max_bound i := Z.ones (log_cap i).
+ Definition rep (us : digits) (x : F modulus) := decode us = x.
+ Local Notation "u ~= x" := (rep u x).
+ Local Hint Unfold rep.
- Fixpoint isFull' us full i :=
- match i with
- | O => andb (Z.ltb (max_bound 0 - c) (nth_default 0 us 0)) full
- | S i' => isFull' us (andb (Z.eqb (max_bound i) (nth_default 0 us i)) full) i'
- end.
+ Definition carry_sequence is (us : digits) : digits := fold_right carry us is.
- Definition isFull us := isFull' us true (length base - 1)%nat.
+ Definition carry_full : digits -> digits := carry_sequence (full_carry_chain limb_widths).
- Fixpoint modulus_digits' i :=
- match i with
- | O => max_bound i - c + 1 :: nil
- | S i' => modulus_digits' i' ++ max_bound i :: nil
- end.
+ Definition carry_mul (us vs : digits) : digits := carry_full (mul us vs).
- (* compute at compile time *)
- Definition modulus_digits := modulus_digits' (length base - 1).
+ Definition freeze (us : digits) : digits :=
+ let us' := carry_full (carry_full (carry_full us)) in
+ from_list (conditional_subtract_modulus [[us']] (ge_modulus [[us']]))
+ (length_conditional_subtract_modulus length_to_list).
- Definition and_term us := if isFull us then max_ones else 0.
+ Definition eq (x y : digits) : Prop := decode x = decode y.
- Definition freeze us :=
- let us' := carry_full (carry_full (carry_full us)) in
- let and_term := and_term us' in
- (* [and_term] is all ones if us' is full, so the subtractions subtract q overall.
- Otherwise, it's all zeroes, and the subtractions do nothing. *)
- map2 (fun x y => x - y) us' (map (Z.land and_term) modulus_digits).
+ Import Morphisms.
+ Global Instance eq_Equivalence : Equivalence eq.
+ Proof.
+ split; cbv [eq]; repeat intro; congruence.
+ Qed.
-End Canonicalization.
+End ModularBaseSystem. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemField.v b/src/ModularArithmetic/ModularBaseSystemField.v
new file mode 100644
index 000000000..f5bedd644
--- /dev/null
+++ b/src/ModularArithmetic/ModularBaseSystemField.v
@@ -0,0 +1,71 @@
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
+Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
+Require Import Crypto.ModularArithmetic.ModularBaseSystem.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
+Require Import Coq.ZArith.ZArith.
+Require Import Crypto.Algebra. Import Field.
+Require Import Crypto.Util.Tuple Crypto.Util.Notations.
+Local Open Scope Z_scope.
+
+Section ModularBaseSystemField.
+ Context `{prm : PseudoMersenneBaseParams} {sc : SubtractionCoefficient modulus prm}
+ (k_ c_ : Z) (k_subst : k = k_) (c_subst : c = c_).
+ Local Notation base := (Pow2Base.base_from_limb_widths limb_widths).
+ Local Notation digits := (tuple Z (length limb_widths)).
+
+ Lemma add_decode : forall a b : digits,
+ decode (add_opt a b) = (decode a + decode b)%F.
+ Proof.
+ intros; rewrite add_opt_correct by assumption.
+ apply add_rep; apply decode_rep.
+ Qed.
+
+ Lemma sub_decode : forall a b : digits,
+ decode (sub_opt a b) = (decode a - decode b)%F.
+ Proof.
+ intros; rewrite sub_opt_correct by assumption.
+ apply sub_rep; auto using coeff_mod, decode_rep.
+ Qed.
+
+ Lemma mul_decode : forall a b : digits,
+ decode (carry_mul_opt k_ c_ a b) = (decode a * decode b)%F.
+ Proof.
+ intros; rewrite carry_mul_opt_correct by assumption.
+ apply carry_mul_rep; apply decode_rep.
+ Qed.
+
+ Lemma zero_neq_one : eq zero one -> False.
+ Proof.
+ cbv [eq zero one]. erewrite !encode_rep. intro A.
+ eapply (PrimeFieldTheorems.Fq_1_neq_0 (prime_q := prime_modulus)).
+ congruence.
+ Qed.
+
+ Lemma modular_base_system_field :
+ @field digits eq zero one opp add_opt sub_opt (carry_mul_opt k_ c_) inv div.
+ Proof.
+ eapply (Field.isomorphism_to_subfield_field (phi := decode) (fieldR := PrimeFieldTheorems.field_modulo (prime_q := prime_modulus))).
+ Grab Existential Variables.
+ + intros; eapply encode_rep.
+ + intros; eapply encode_rep.
+ + intros; eapply encode_rep.
+ + intros; eapply encode_rep.
+ + intros; eapply mul_decode.
+ + intros; eapply sub_decode.
+ + intros; eapply add_decode.
+ + intros; eapply encode_rep.
+ + cbv [eq zero one]. erewrite !encode_rep. intro A.
+ eapply (PrimeFieldTheorems.Fq_1_neq_0 (prime_q := prime_modulus)).
+ congruence.
+ + trivial.
+ + repeat intro. cbv [div]. congruence.
+ + repeat intro. cbv [inv]. congruence.
+ + repeat intro. cbv [eq]. erewrite !mul_decode. congruence.
+ + repeat intro. cbv [eq]. erewrite !sub_decode. congruence.
+ + repeat intro. cbv [eq]. erewrite !add_decode. congruence.
+ + repeat intro. cbv [opp]. congruence.
+ + cbv [eq]. auto using ModularArithmeticTheorems.F_eq_dec.
+ Qed.
+
+End ModularBaseSystemField. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemInterface.v b/src/ModularArithmetic/ModularBaseSystemInterface.v
deleted file mode 100644
index c79dce1d3..000000000
--- a/src/ModularArithmetic/ModularBaseSystemInterface.v
+++ /dev/null
@@ -1,150 +0,0 @@
-Require Import Crypto.BaseSystem.
-Require Import Crypto.ModularArithmetic.ModularBaseSystem.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemProofs.
-Require Import Crypto.BaseSystemProofs.
-Require Import Crypto.Util.Tuple Crypto.Util.CaseUtil.
-Require Import ZArith.
-Require Import Crypto.Algebra.
-Import Group.
-Import PseudoMersenneBaseParams PseudoMersenneBaseParamProofs.
-
-Generalizable All Variables.
-Section s.
- Context `{prm:PseudoMersenneBaseParams m} {sc : SubtractionCoefficient m prm}.
- Context {k_ c_} (pfk : k = k_) (pfc:c = c_).
- Local Notation base := (Pow2Base.base_from_limb_widths limb_widths).
-
- Definition fe := tuple Z (length base).
-
- Arguments to_list {_ _} _.
-
- Definition mul (x y:fe) : fe :=
- carry_mul_opt_cps k_ c_ (from_list_default 0%Z (length base))
- (to_list x) (to_list y).
-
- Definition add (x y : fe) : fe :=
- from_list_default 0%Z (length base) (add_opt (to_list x) (to_list y)).
-
- Definition sub : fe -> fe -> fe.
- refine (on_tuple2 sub_opt _).
- abstract (intros; rewrite sub_opt_correct; apply length_sub; rewrite ?coeff_length; auto).
- Defined.
-
- Definition phi (a : fe) : ModularArithmetic.F m := decode (to_list a).
- Definition phi_inv (a : ModularArithmetic.F m) : fe :=
- from_list_default 0%Z _ (encode a).
-
- Lemma phi_inv_spec : forall a, phi (phi_inv a) = a.
- Proof.
- intros; cbv [phi_inv phi].
- erewrite from_list_default_eq.
- rewrite to_list_from_list.
- apply ModularBaseSystemProofs.encode_rep.
- Grab Existential Variables.
- apply ModularBaseSystemProofs.encode_rep.
- Qed.
-
- Definition eq (x y : fe) : Prop := phi x = phi y.
-
- Import Morphisms.
- Global Instance eq_Equivalence : Equivalence eq.
- Proof.
- split; cbv [eq]; repeat intro; congruence.
- Qed.
-
- Lemma phi_inv_spec_reverse : forall a, eq (phi_inv (phi a)) a.
- Proof.
- intros. unfold eq. rewrite phi_inv_spec; reflexivity.
- Qed.
-
- Definition zero : fe := phi_inv (ModularArithmetic.ZToField 0).
-
- Definition opp (x : fe) : fe := phi_inv (ModularArithmetic.opp (phi x)).
-
- Definition one : fe := phi_inv (ModularArithmetic.ZToField 1).
-
- Definition inv (x : fe) : fe := phi_inv (ModularArithmetic.inv (phi x)).
-
- Definition div (x y : fe) : fe := phi_inv (ModularArithmetic.div (phi x) (phi y)).
-
- Lemma add_correct : forall a b,
- to_list (add a b) = BaseSystem.add (to_list a) (to_list b).
- Proof.
- intros; cbv [add].
- rewrite add_opt_correct.
- erewrite from_list_default_eq.
- apply to_list_from_list.
- Grab Existential Variables.
- apply add_same_length; auto using length_to_list.
- Qed.
-
- Lemma add_phi : forall a b : fe,
- phi (add a b) = ModularArithmetic.add (phi a) (phi b).
- Proof.
- intros; cbv [phi].
- rewrite add_correct.
- apply ModularBaseSystemProofs.add_rep; auto using decode_rep, length_to_list.
- Qed.
-
- Lemma sub_correct : forall a b,
- to_list (sub a b) = ModularBaseSystem.sub coeff (to_list a) (to_list b).
- Proof.
- intros; cbv [sub on_tuple2].
- rewrite to_list_from_list.
- apply sub_opt_correct.
- Qed.
-
- Lemma sub_phi : forall a b : fe,
- phi (sub a b) = ModularArithmetic.sub (phi a) (phi b).
- Proof.
- intros; cbv [phi].
- rewrite sub_correct.
- apply ModularBaseSystemProofs.sub_rep; auto using decode_rep, length_to_list,
- coeff_length, coeff_mod.
- Qed.
-
- Lemma mul_correct : forall a b,
- to_list (mul a b) = carry_mul (to_list a) (to_list b).
- Proof.
- intros; cbv [mul].
- rewrite carry_mul_opt_cps_correct by assumption.
- erewrite from_list_default_eq.
- apply to_list_from_list.
- Grab Existential Variables.
- apply carry_mul_length; apply length_to_list.
- Qed.
-
- Lemma mul_phi : forall a b : fe,
- phi (mul a b) = ModularArithmetic.mul (phi a) (phi b).
- Proof.
- intros; cbv beta delta [phi].
- rewrite mul_correct.
- apply carry_mul_rep; auto using decode_rep, length_to_list.
- Qed.
-
- Lemma modular_base_system_field : @field fe eq zero one opp add sub mul inv div.
- Proof.
- eapply (Field.isomorphism_to_subfield_field (phi := phi) (fieldR := PrimeFieldTheorems.field_modulo (prime_q := prime_modulus))).
- Grab Existential Variables.
- + intros; eapply phi_inv_spec.
- + intros; eapply phi_inv_spec.
- + intros; eapply phi_inv_spec.
- + intros; eapply phi_inv_spec.
- + intros; eapply mul_phi.
- + intros; eapply sub_phi.
- + intros; eapply add_phi.
- + intros; eapply phi_inv_spec.
- + cbv [eq zero one]. erewrite !phi_inv_spec. intro A.
- eapply (PrimeFieldTheorems.Fq_1_neq_0 (prime_q := prime_modulus)). congruence.
- + trivial.
- + repeat intro. cbv [div]. congruence.
- + repeat intro. cbv [inv]. congruence.
- + repeat intro. cbv [eq]. erewrite !mul_phi. congruence.
- + repeat intro. cbv [eq]. erewrite !sub_phi. congruence.
- + repeat intro. cbv [eq]. erewrite !add_phi. congruence.
- + repeat intro. cbv [opp]. congruence.
- + cbv [eq]. auto using ModularArithmeticTheorems.F_eq_dec.
- Qed.
-
-End s. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemList.v b/src/ModularArithmetic/ModularBaseSystemList.v
new file mode 100644
index 000000000..07b2c2bac
--- /dev/null
+++ b/src/ModularArithmetic/ModularBaseSystemList.v
@@ -0,0 +1,69 @@
+Require Import Coq.ZArith.Zpower Coq.ZArith.ZArith.
+Require Import Coq.Lists.List.
+Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil.
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
+Require Import Crypto.BaseSystem.
+Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
+Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
+Require Import Crypto.Tactics.VerdiTactics.
+Require Import Crypto.Util.Notations.
+Require Import Crypto.ModularArithmetic.Pow2Base.
+Local Open Scope Z_scope.
+
+Section Defs.
+ Context `{prm :PseudoMersenneBaseParams} (modulus_multiple : digits).
+ Local Notation base := (base_from_limb_widths limb_widths).
+ Local Notation "u [ i ]" := (nth_default 0 u i) (at level 40).
+
+ Definition decode (us : digits) : F modulus := ZToField (BaseSystem.decode base us).
+
+ Definition encode (x : F modulus) := encodeZ limb_widths x.
+
+ (* Converts from length of extended base to length of base by reduction modulo M.*)
+ Definition reduce (us : digits) : digits :=
+ let high := skipn (length limb_widths) us in
+ let low := firstn (length limb_widths) us in
+ let wrap := map (Z.mul c) high in
+ BaseSystem.add low wrap.
+
+ Definition mul (us vs : digits) := reduce (BaseSystem.mul (ext_base limb_widths) us vs).
+
+ (* In order to subtract without underflowing, we add a multiple of the modulus first. *)
+ Definition sub (us vs : digits) := BaseSystem.sub (add modulus_multiple us) vs.
+
+ (*
+ Definition carry_and_reduce :=
+ carry_gen limb_widths (fun ci => c * ci).
+ *)
+ Definition carry_and_reduce i := fun us =>
+ let di := us [i] in
+ let us' := set_nth i (Z.pow2_mod di (limb_widths [i])) us in
+ add_to_nth 0 (c * (Z.shiftr di (limb_widths [i]))) us'.
+
+ Definition carry i : digits -> digits :=
+ if eq_nat_dec i (pred (length base))
+ then carry_and_reduce i
+ else carry_simple limb_widths i.
+
+ Definition modulus_digits := encodeZ limb_widths modulus.
+
+ (* compute at compile time *)
+ Definition max_ones := Z.ones (fold_right Z.max 0 limb_widths).
+
+ (* Constant-time comparison with modulus; only works if all digits of [us]
+ are less than 2 ^ their respective limb width. *)
+ Fixpoint ge_modulus' us acc i :=
+ match i with
+ | O => andb (Z.ltb (modulus_digits [0]) (us [0])) acc
+ | S i' => ge_modulus' us (andb (Z.eqb (modulus_digits [i]) (us [i])) acc) i'
+ end.
+
+ Definition ge_modulus us := ge_modulus' us true (length base - 1)%nat.
+
+ Definition conditional_subtract_modulus (us : digits) (cond : bool) :=
+ let and_term := if cond then max_ones else 0 in
+ (* [and_term] is all ones if us' is full, so the subtractions subtract q overall.
+ Otherwise, it's all zeroes, and the subtractions do nothing. *)
+ map2 (fun x y => x - y) us (map (Z.land and_term) modulus_digits).
+
+End Defs. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemListProofs.v b/src/ModularArithmetic/ModularBaseSystemListProofs.v
new file mode 100644
index 000000000..35de02cde
--- /dev/null
+++ b/src/ModularArithmetic/ModularBaseSystemListProofs.v
@@ -0,0 +1,95 @@
+Require Import Zpower ZArith.
+Require Import Coq.Numbers.Natural.Peano.NPeano.
+Require Import List.
+Require Import VerdiTactics.
+Require Import Crypto.BaseSystemProofs.
+Require Import Crypto.ModularArithmetic.Pow2Base.
+Require Import Crypto.ModularArithmetic.Pow2BaseProofs.
+Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
+Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
+Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
+Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.ListUtil.
+Require Import Crypto.Util.Notations.
+
+Require Import Crypto.ModularArithmetic.ModularBaseSystemList.
+Local Open Scope Z_scope.
+
+Section LengthProofs.
+ Context `{prm :PseudoMersenneBaseParams}.
+ Local Notation base := (base_from_limb_widths limb_widths).
+
+ Lemma length_encode {x} : length (encode x) = length limb_widths.
+ Proof.
+ cbv [encode encodeZ]; intros.
+ rewrite encode'_spec;
+ auto using encode'_length, limb_widths_nonneg, Nat.eq_le_incl, base_from_limb_widths_length.
+ Qed.
+
+ Lemma length_reduce : forall us,
+ (length limb_widths <= length us <= length (ext_base limb_widths))%nat ->
+ (length (reduce us) = length limb_widths)%nat.
+ Proof.
+ rewrite extended_base_length.
+ unfold reduce; intros.
+ rewrite add_length_exact.
+ pose proof (@base_from_limb_widths_length limb_widths).
+ rewrite map_length, firstn_length, skipn_length, Min.min_l, Max.max_l;
+ omega.
+ Qed.
+
+ Lemma length_mul {u v} :
+ length u = length limb_widths
+ -> length v = length limb_widths
+ -> length (mul u v) = length limb_widths.
+ Proof.
+ cbv [mul]; intros.
+ apply length_reduce.
+ destruct u; try congruence.
+ + rewrite @nil_length0 in *; omega.
+ + rewrite mul_length_exact, extended_base_length, base_from_limb_widths_length; try omega.
+ congruence.
+ Qed.
+
+ Section Sub.
+ Context {mm : list Z} (mm_length : length mm = length limb_widths).
+
+ Lemma length_sub {u v} :
+ length u = length limb_widths
+ -> length v = length limb_widths
+ -> length (sub mm u v) = length limb_widths.
+ Proof.
+ cbv [sub]; intros.
+ rewrite sub_length, add_length_exact.
+ repeat rewrite Max.max_r; omega.
+ Qed.
+ End Sub.
+
+ Lemma length_carry_and_reduce {us}: forall i, length (carry_and_reduce i us) = length us.
+ Proof. intros; unfold carry_and_reduce; autorewrite with distr_length; reflexivity. Qed.
+ Hint Rewrite @length_carry_and_reduce : distr_length.
+
+ Lemma length_carry {u i} :
+ length u = length limb_widths
+ -> length (carry i u) = length limb_widths.
+ Proof. intros; unfold carry; break_if; autorewrite with distr_length; omega. Qed.
+ Hint Rewrite @length_carry : distr_length.
+
+ Lemma length_modulus_digits : length modulus_digits = length limb_widths.
+ Proof.
+ intros; unfold modulus_digits, encodeZ.
+ rewrite encode'_spec, encode'_length;
+ auto using encode'_length, limb_widths_nonneg, Nat.eq_le_incl, base_from_limb_widths_length.
+ Qed.
+
+ Lemma length_conditional_subtract_modulus {u cond} :
+ length u = length limb_widths
+ -> length (conditional_subtract_modulus u cond) = length limb_widths.
+ Proof.
+ intros; unfold conditional_subtract_modulus.
+ rewrite map2_length, map_length, length_modulus_digits.
+ apply Min.min_case; omega.
+ Qed.
+
+End LengthProofs. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemOpt.v b/src/ModularArithmetic/ModularBaseSystemOpt.v
index 1e748892d..ed8f80659 100644
--- a/src/ModularArithmetic/ModularBaseSystemOpt.v
+++ b/src/ModularArithmetic/ModularBaseSystemOpt.v
@@ -4,8 +4,12 @@ Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
Require Import Crypto.ModularArithmetic.ModularBaseSystemProofs.
Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
Require Import Crypto.ModularArithmetic.Pow2BaseProofs.
-Require Import Crypto.BaseSystem Crypto.ModularArithmetic.ModularBaseSystem.
+Require Import Crypto.BaseSystem.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemList.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemListProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystem.
Require Import Coq.Lists.List.
+Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.ListUtil Crypto.Util.ZUtil Crypto.Util.NatUtil Crypto.Util.CaseUtil.
Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
@@ -14,8 +18,7 @@ Require Import Crypto.Tactics.VerdiTactics.
Local Open Scope Z.
Class SubtractionCoefficient (m : Z) (prm : PseudoMersenneBaseParams m) := {
- coeff : BaseSystem.digits;
- coeff_length : (length coeff = length (Pow2Base.base_from_limb_widths limb_widths))%nat;
+ coeff : tuple Z (length limb_widths);
coeff_mod: decode coeff = 0%F
}.
@@ -37,9 +40,9 @@ Definition map_opt {A B} := Eval compute in @map A B.
Definition full_carry_chain_opt := Eval compute in @Pow2Base.full_carry_chain.
Definition length_opt := Eval compute in length.
Definition base_from_limb_widths_opt := Eval compute in @Pow2Base.base_from_limb_widths.
-Definition max_ones_opt := Eval compute in @max_ones.
-Definition max_bound_opt := Eval compute in @max_bound.
Definition minus_opt := Eval compute in minus.
+Definition max_ones_opt := Eval compute in @max_ones.
+Definition from_list_default_opt {A} := Eval compute in (@from_list_default A).
Definition Let_In {A P} (x : A) (f : forall y : A, P y)
:= let y := x in f y.
@@ -110,14 +113,16 @@ Section Carries.
(* allows caller to precompute k and c *)
(k_ c_ : Z) (k_subst : k = k_) (c_subst : c = c_).
Local Notation base := (Pow2Base.base_from_limb_widths limb_widths).
+ Local Notation digits := (tuple Z (length limb_widths)).
Definition carry_opt_sig
(i : nat) (b : digits)
: { d : digits | (i < length limb_widths)%nat -> d = carry i b }.
Proof.
eexists ; intros.
- cbv [carry].
- rewrite <- pull_app_if_sumbool.
+ cbv [carry ModularBaseSystemList.carry].
+ rewrite <-from_list_default_eq with (d := 0%Z).
+ rewrite <-pull_app_if_sumbool.
cbv beta delta
[carry carry_and_reduce Pow2Base.carry_gen Pow2Base.carry_and_reduce_single Pow2Base.carry_simple
Z.pow2_mod Z.ones Z.pred
@@ -127,12 +132,13 @@ Section Carries.
change @nth_default with @nth_default_opt in *.
change @set_nth with @set_nth_opt in *.
lazymatch goal with
- | [ |- _ = (if ?br then ?c else ?d) ]
+ | [ |- _ = _ (if ?br then ?c else ?d) ]
=> let x := fresh "x" in let y := fresh "y" in evar (x:digits); evar (y:digits); transitivity (if br then x else y); subst x; subst y
end.
2:cbv zeta.
2:break_if; reflexivity.
+ change @from_list_default with @from_list_default_opt.
change @nth_default with @nth_default_opt.
rewrite c_subst.
change @set_nth with @set_nth_opt.
@@ -141,10 +147,12 @@ Section Carries.
reflexivity.
Defined.
- Definition carry_opt i b
- := Eval cbv beta iota delta [proj1_sig carry_opt_sig] in proj1_sig (carry_opt_sig i b).
+ Definition carry_opt is us := Eval cbv [proj1_sig carry_opt_sig] in
+ proj1_sig (carry_opt_sig is us).
- Definition carry_opt_correct i b : (i < length limb_widths)%nat -> carry_opt i b = carry i b := proj2_sig (carry_opt_sig i b).
+ Definition carry_opt_correct i us
+ : (i < length limb_widths)%nat -> carry_opt i us = carry i us
+ := proj2_sig (carry_opt_sig i us).
Definition carry_sequence_opt_sig (is : list nat) (us : digits)
: { b : digits | (forall i, In i is -> i < length base)%nat -> b = carry_sequence is us }.
@@ -183,11 +191,10 @@ Section Carries.
cbv beta iota delta [carry_opt].
let LHS := match goal with |- ?LHS = ?RHS => LHS end in
let RHS := match goal with |- ?LHS = ?RHS => RHS end in
- let RHSf := match (eval pattern (nth_default_opt 0%Z b i) in RHS) with ?RHSf _ => RHSf end in
- change (LHS = Let_In (nth_default_opt 0%Z b i) RHSf).
+ let RHSf := match (eval pattern (nth_default_opt 0%Z (to_list _ b) i) in RHS) with ?RHSf _ => RHSf end in
+ change (LHS = Let_In (nth_default_opt 0%Z (to_list _ b) i) RHSf).
change Z.shiftl with Z_shiftl_opt.
- change (-1) with (Z_opp_opt 1).
- change Z.add with Z_add_opt at 5 9 17 21.
+ match goal with |- appcontext[ ?x + -1] => change (x + -1) with (Z_add_opt x (Z_opp_opt 1)) end.
reflexivity.
Defined.
@@ -265,13 +272,13 @@ Section Carries.
Lemma carry_sequence_opt_cps_rep
- : forall (is : list nat) (us : list Z) (x : F modulus),
+ : forall (is : list nat) (us : digits) (x : F modulus),
(forall i : nat, In i is -> i < length base)%nat ->
rep us x -> rep (carry_sequence_opt_cps is us) x.
Proof.
intros.
rewrite carry_sequence_opt_cps_correct by assumption.
- apply carry_sequence_rep; eauto using rep_length.
+ auto using carry_sequence_rep.
Qed.
Lemma full_carry_chain_bounds : forall i, In i (Pow2Base.full_carry_chain limb_widths) -> (i < length base)%nat.
@@ -320,6 +327,7 @@ End Carries.
Section Addition.
Context `{prm : PseudoMersenneBaseParams} {sc : SubtractionCoefficient modulus prm}.
+ Local Notation digits := (tuple Z (length limb_widths)).
Definition add_opt_sig (us vs : digits) : { b : digits | b = add us vs }.
Proof.
@@ -338,6 +346,7 @@ End Addition.
Section Subtraction.
Context `{prm : PseudoMersenneBaseParams} {sc : SubtractionCoefficient modulus prm}.
+ Local Notation digits := (tuple Z (length limb_widths)).
Definition sub_opt_sig (us vs : digits) : { b : digits | b = sub coeff us vs }.
Proof.
@@ -358,9 +367,11 @@ Section Multiplication.
Context `{prm : PseudoMersenneBaseParams} {sc : SubtractionCoefficient modulus prm}
(* allows caller to precompute k and c *)
(k_ c_ : Z) (k_subst : k = k_) (c_subst : c = c_).
+ Local Notation digits := (tuple Z (length limb_widths)).
+
Definition mul_bi'_step
- (mul_bi' : nat -> digits -> list Z -> list Z)
- (i : nat) (vsr : digits) (bs : list Z)
+ (mul_bi' : nat -> list Z -> list Z -> list Z)
+ (i : nat) (vsr : list Z) (bs : list Z)
: list Z
:= match vsr with
| [] => []
@@ -368,8 +379,8 @@ Section Multiplication.
end.
Definition mul_bi'_opt_step_sig
- (mul_bi' : nat -> digits -> list Z -> list Z)
- (i : nat) (vsr : digits) (bs : list Z)
+ (mul_bi' : nat -> list Z -> list Z -> list Z)
+ (i : nat) (vsr : list Z) (bs : list Z)
: { l : list Z | l = mul_bi'_step mul_bi' i vsr bs }.
Proof.
eexists.
@@ -384,19 +395,19 @@ Section Multiplication.
Defined.
Definition mul_bi'_opt_step
- (mul_bi' : nat -> digits -> list Z -> list Z)
- (i : nat) (vsr : digits) (bs : list Z)
+ (mul_bi' : nat -> list Z -> list Z -> list Z)
+ (i : nat) (vsr : list Z) (bs : list Z)
: list Z
:= Eval cbv [proj1_sig mul_bi'_opt_step_sig] in
proj1_sig (mul_bi'_opt_step_sig mul_bi' i vsr bs).
Fixpoint mul_bi'_opt
- (i : nat) (vsr : digits) (bs : list Z) {struct vsr}
+ (i : nat) (vsr : list Z) (bs : list Z) {struct vsr}
: list Z
:= mul_bi'_opt_step mul_bi'_opt i vsr bs.
Definition mul_bi'_opt_correct
- (i : nat) (vsr : digits) (bs : list Z)
+ (i : nat) (vsr : list Z) (bs : list Z)
: mul_bi'_opt i vsr bs = mul_bi' bs i vsr.
Proof.
revert i; induction vsr as [|vsr vsrs IHvsr]; intros.
@@ -413,12 +424,12 @@ Section Multiplication.
Qed.
Definition mul'_step
- (mul' : digits -> digits -> list Z -> digits)
- (usr vs : digits) (bs : list Z)
- : digits
+ (mul' : list Z -> list Z -> list Z -> list Z)
+ (usr vs : list Z) (bs : list Z)
+ : list Z
:= match usr with
| [] => []
- | u :: usr' => add (mul_each u (mul_bi bs (length usr') vs)) (mul' usr' vs bs)
+ | u :: usr' => BaseSystem.add (mul_each u (mul_bi bs (length usr') vs)) (mul' usr' vs bs)
end.
Lemma map_zeros : forall a n l,
@@ -428,9 +439,9 @@ Section Multiplication.
Qed.
Definition mul'_opt_step_sig
- (mul' : digits -> digits -> list Z -> digits)
- (usr vs : digits) (bs : list Z)
- : { d : digits | d = mul'_step mul' usr vs bs }.
+ (mul' : list Z -> list Z -> list Z -> list Z)
+ (usr vs : list Z) (bs : list Z)
+ : { d : list Z | d = mul'_step mul' usr vs bs }.
Proof.
eexists.
cbv [mul'_step].
@@ -449,18 +460,18 @@ Section Multiplication.
Defined.
Definition mul'_opt_step
- (mul' : digits -> digits -> list Z -> digits)
- (usr vs : digits) (bs : list Z)
- : digits
+ (mul' : list Z -> list Z -> list Z -> list Z)
+ (usr vs : list Z) (bs : list Z)
+ : list Z
:= Eval cbv [proj1_sig mul'_opt_step_sig] in proj1_sig (mul'_opt_step_sig mul' usr vs bs).
Fixpoint mul'_opt
- (usr vs : digits) (bs : list Z)
- : digits
+ (usr vs : list Z) (bs : list Z)
+ : list Z
:= mul'_opt_step mul'_opt usr vs bs.
Definition mul'_opt_correct
- (usr vs : digits) (bs : list Z)
+ (usr vs : list Z) (bs : list Z)
: mul'_opt usr vs bs = mul' bs usr vs.
Proof.
revert vs; induction usr as [|usr usrs IHusr]; intros.
@@ -471,13 +482,17 @@ Section Multiplication.
cbv [mul_each mul_bi].
rewrite map_zeros.
rewrite <- mul_bi'_opt_correct.
+ cbv [zeros].
reflexivity. }
Qed.
Definition mul_opt_sig (us vs : digits) : { b : digits | b = mul us vs }.
Proof.
eexists.
- cbv [BaseSystem.mul mul mul_each mul_bi mul_bi' zeros reduce].
+ cbv [mul ModularBaseSystemList.mul BaseSystem.mul mul_each mul_bi mul_bi' zeros reduce].
+ rewrite <- from_list_default_eq with (d := 0%Z).
+ change (@from_list_default Z) with (@from_list_default_opt Z).
+ apply f_equal.
rewrite ext_base_alt by auto using limb_widths_pos with zarith.
rewrite <- mul'_opt_correct.
change @Pow2Base.base_from_limb_widths with base_from_limb_widths_opt.
@@ -512,6 +527,13 @@ Section Multiplication.
Definition carry_mul_opt_cps_correct {T} (f:digits -> T) (us vs : digits)
: carry_mul_opt_cps f us vs = f (carry_mul us vs)
:= proj2_sig (carry_mul_opt_sig f us vs).
+
+ Definition carry_mul_opt := carry_mul_opt_cps id.
+
+ Definition carry_mul_opt_correct (us vs : digits)
+ : carry_mul_opt us vs = carry_mul us vs :=
+ carry_mul_opt_cps_correct id us vs.
+
End Multiplication.
Section with_base.
@@ -525,8 +547,8 @@ Section with_base.
int_width_pos : 0 < int_width;
int_width_compat : forall w, In w limb_widths -> w <= int_width;
c_pos : 0 < c;
- c_reduce1 : c * (Z.ones (int_width - log_cap (pred (length base)))) < max_bound 0 + 1;
- c_reduce2 : c <= max_bound 0 - c;
+ c_reduce1 : c * (Z.ones (int_width - log_cap (pred (length base)))) < 2 ^ log_cap 0;
+ c_reduce2 : c < 2 ^ log_cap 0 - c;
two_pow_k_le_2modulus : 2 ^ k <= 2 * modulus
}.
End with_base.
@@ -538,30 +560,26 @@ Section Canonicalization.
(* allows caller to precompute k and c *)
(k_ c_ : Z) (k_subst : k = k_) (c_subst : c = c_)
{int_width} (preconditions : freezePreconditions prm int_width).
+ Local Notation digits := (tuple Z (length limb_widths)).
+
+ Definition encodeZ_opt := Eval compute in Pow2Base.encodeZ.
Definition modulus_digits_opt_sig :
- { b : digits | b = modulus_digits }.
+ { b : list Z | b = modulus_digits }.
Proof.
eexists.
- cbv beta iota delta [modulus_digits modulus_digits' app].
- change @max_bound with max_bound_opt.
- rewrite c_subst.
- change length with length_opt.
- change minus with minus_opt.
- change Z.add with Z_add_opt.
- change Z.sub with Z_sub_opt.
- change @Pow2Base.base_from_limb_widths with base_from_limb_widths_opt.
+ cbv beta iota delta [modulus_digits].
+ change Pow2Base.encodeZ with encodeZ_opt.
reflexivity.
Defined.
- Definition modulus_digits_opt : digits
+ Definition modulus_digits_opt : list Z
:= Eval cbv [proj1_sig modulus_digits_opt_sig] in proj1_sig (modulus_digits_opt_sig).
Definition modulus_digits_opt_correct
: modulus_digits_opt = modulus_digits
:= proj2_sig (modulus_digits_opt_sig).
-
Definition carry_full_3_opt_cps_sig
{T} (f : digits -> T)
(us : digits)
@@ -587,20 +605,20 @@ Section Canonicalization.
{ b : digits | b = freeze us }.
Proof.
eexists.
- cbv [freeze].
- cbv [and_term].
+ cbv [freeze conditional_subtract_modulus].
+ rewrite <-from_list_default_eq with (d := 0%Z).
+ change (@from_list_default Z) with (@from_list_default_opt Z).
let LHS := match goal with |- ?LHS = ?RHS => LHS end in
let RHS := match goal with |- ?LHS = ?RHS => RHS end in
- let RHSf := match (eval pattern (isFull (carry_full (carry_full (carry_full us)))) in RHS) with ?RHSf _ => RHSf end in
- change (LHS = Let_In (isFull(carry_full (carry_full (carry_full us)))) RHSf).
+ let RHSf := match (eval pattern (to_list (length limb_widths) (carry_full (carry_full (carry_full us)))) in RHS) with ?RHSf _ => RHSf end in
+ change (LHS = Let_In (to_list (length limb_widths) (carry_full (carry_full (carry_full us)))) RHSf).
let LHS := match goal with |- ?LHS = ?RHS => LHS end in
let RHS := match goal with |- ?LHS = ?RHS => RHS end in
let RHSf := match (eval pattern (carry_full (carry_full (carry_full us))) in RHS) with ?RHSf _ => RHSf end in
rewrite <-carry_full_3_opt_cps_correct with (f := RHSf).
- cbv beta iota delta [and_term isFull isFull'].
+ cbv beta iota delta [ge_modulus ge_modulus'].
change length with length_opt.
- change @max_bound with max_bound_opt.
- rewrite c_subst.
+ change (nth_default 0 modulus_digits) with (nth_default_opt 0 modulus_digits_opt).
change @max_ones with max_ones_opt.
change @Pow2Base.base_from_limb_widths with base_from_limb_widths_opt.
change minus with minus_opt.
@@ -616,7 +634,7 @@ Section Canonicalization.
Definition freeze_opt_correct us
: freeze_opt us = freeze us
:= proj2_sig (freeze_opt_sig us).
-
+(*
Lemma freeze_opt_canonical: forall us vs x,
@pre_carry_bounds _ _ int_width us -> rep us x ->
@pre_carry_bounds _ _ int_width vs -> rep vs x ->
@@ -643,5 +661,5 @@ Section Canonicalization.
split; eauto using freeze_opt_canonical.
auto using freeze_opt_preserves_rep.
Qed.
-
-End Canonicalization.
+*)
+End Canonicalization. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemProofs.v b/src/ModularArithmetic/ModularBaseSystemProofs.v
index b815167e2..e6351dc17 100644
--- a/src/ModularArithmetic/ModularBaseSystemProofs.v
+++ b/src/ModularArithmetic/ModularBaseSystemProofs.v
@@ -1,15 +1,20 @@
Require Import Coq.ZArith.Zpower Coq.ZArith.ZArith.
Require Import Coq.Numbers.Natural.Peano.NPeano.
Require Import Coq.Lists.List.
-Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil Crypto.Util.NatUtil.
Require Import Crypto.Tactics.VerdiTactics.
-Require Crypto.BaseSystem.
-Require Import Crypto.ModularArithmetic.ModularBaseSystem Crypto.ModularArithmetic.PrimeFieldTheorems.
-Require Import Crypto.BaseSystemProofs Crypto.ModularArithmetic.Pow2Base.
+Require Import Crypto.BaseSystem.
+Require Import Crypto.BaseSystemProofs.
+Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
+Require Import Crypto.ModularArithmetic.Pow2Base.
Require Import Crypto.ModularArithmetic.Pow2BaseProofs.
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
-Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemList.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemListProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystem.
+Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil Crypto.Util.NatUtil.
+Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Local Open Scope Z_scope.
@@ -19,29 +24,26 @@ Local Opaque add_to_nth carry_simple.
Section PseudoMersenneProofs.
Context `{prm :PseudoMersenneBaseParams}.
+ Local Arguments to_list {_ _} _.
+ Local Arguments from_list {_ _} _ _.
+
Local Hint Unfold decode.
Local Notation "u ~= x" := (rep u x).
- Local Notation "u .+ x" := (add u x).
- Local Notation "u .* x" := (ModularBaseSystem.mul u x).
- Local Hint Unfold rep.
+ Local Notation digits := (tuple Z (length limb_widths)).
Local Hint Resolve (@limb_widths_nonneg _ prm) sum_firstn_limb_widths_nonneg.
Local Hint Resolve log_cap_nonneg.
Local Notation base := (base_from_limb_widths limb_widths).
Local Notation log_cap i := (nth_default 0 limb_widths i).
- Lemma rep_decode : forall us x, us ~= x -> decode us = x.
- Proof.
- autounfold; intuition auto.
- Qed.
+ Local Hint Unfold rep decode ModularBaseSystemList.decode.
- Lemma rep_length : forall us x, us ~= x -> length us = length base.
+ Lemma rep_decode : forall us x, us ~= x -> decode us = x.
Proof.
- autounfold; intuition auto.
+ autounfold; intuition.
Qed.
- Lemma decode_rep : forall us, length us = length base ->
- rep us (decode us).
+ Lemma decode_rep : forall us, rep us (decode us).
Proof.
cbv [rep]; auto.
Qed.
@@ -73,75 +75,32 @@ Section PseudoMersenneProofs.
destruct limb_widths; simpl in *; congruence.
Qed.
- Lemma encode'_eq : forall (x : F modulus) i, (i <= length limb_widths)%nat ->
- encode' limb_widths x i = BaseSystem.encode' base x (2 ^ k) i.
+ Lemma encode_eq : forall x : F modulus,
+ ModularBaseSystemList.encode x = BaseSystem.encode base x (2 ^ k).
Proof.
- rewrite <-base_length; induction i; intros.
- + rewrite encode'_zero. reflexivity.
- + rewrite encode'_succ, <-IHi by omega.
- simpl; do 2 f_equal.
- rewrite Z.land_ones, Z.shiftr_div_pow2 by eauto.
- match goal with H : (S _ <= length base)%nat |- _ =>
- apply le_lt_or_eq in H; destruct H end.
- - repeat f_equal; rewrite nth_default_base by (eauto || omega); reflexivity.
- - repeat f_equal; try solve [rewrite nth_default_base by (eauto || omega); reflexivity].
- rewrite nth_default_out_of_bounds by omega.
- unfold k.
- rewrite <-base_length; congruence.
+ cbv [ModularBaseSystemList.encode BaseSystem.encode encodeZ]; intros.
+ rewrite base_length.
+ apply encode'_spec; auto using Nat.eq_le_incl, base_length.
Qed.
- Lemma encode_eq : forall x : F modulus,
- encode x = BaseSystem.encode base x (2 ^ k).
+ Lemma encode_rep : forall x : F modulus, encode x ~= x.
Proof.
- unfold encode, BaseSystem.encode; intros.
- rewrite base_length; apply encode'_eq; omega.
+ autounfold; cbv [encode]; intros.
+ rewrite to_list_from_list; autounfold.
+ rewrite encode_eq, encode_rep.
+ + apply ZToField_FieldToZ.
+ + apply bv.
+ + split; [ | etransitivity]; try (apply FieldToZ_range; auto using modulus_pos); auto.
+ + eauto using base_upper_bound_compatible, limb_widths_nonneg.
Qed.
- Lemma encode_rep : forall x : F modulus, encode x ~= x.
+ Lemma add_rep : forall u v x y, u ~= x -> v ~= y ->
+ add u v ~= (x+y)%F.
Proof.
- intros.
- rewrite encode_eq.
- unfold encode, rep.
- split. {
- unfold BaseSystem.encode.
- auto using encode'_length.
- } {
- unfold decode.
- rewrite encode_rep.
- + apply ZToField_FieldToZ.
- + apply bv.
- + split; [ | etransitivity]; try (apply FieldToZ_range; auto using modulus_pos); auto.
- + unfold base_max_succ_divide; intros.
- match goal with H : (_ <= length base)%nat |- _ =>
- apply le_lt_or_eq in H; destruct H end.
- - apply Z.mod_divide.
- * apply nth_default_base_nonzero, two_sum_firstn_limb_widths_nonzero; auto using bv.
- * rewrite !nth_default_eq.
- do 2 (erewrite nth_indep with (d := 2 ^ k) (d' := 0) by omega).
- rewrite <-!nth_default_eq.
- apply base_succ; eauto; omega.
- - rewrite nth_default_out_of_bounds with (n := S i) by omega.
- rewrite nth_default_base by (omega || eauto).
- unfold k.
- match goal with H : S _ = length base |- _ =>
- rewrite base_length in H; rewrite <-H end.
- erewrite sum_firstn_succ by (apply nth_error_Some_nth_default with (x0 := 0); omega).
- rewrite Z.pow_add_r by (eauto using sum_firstn_limb_widths_nonneg;
- apply limb_widths_nonneg; rewrite nth_default_eq; apply nth_In; omega).
- apply Z.divide_factor_r.
- }
- Qed.
-
- Lemma add_rep : forall u v x y, u ~= x -> v ~= y -> BaseSystem.add u v ~= (x+y)%F.
- Proof.
- autounfold; intuition auto. {
- unfold add.
- auto using add_same_length.
- }
- unfold decode in *; unfold decode in *.
- rewrite add_rep.
- rewrite ZToField_add.
- subst; auto.
+ autounfold; cbv [add]; intros.
+ rewrite to_list_from_list; autounfold.
+ rewrite add_rep, ZToField_add.
+ f_equal; assumption.
Qed.
Local Hint Resolve firstn_us_base_ext_base bv ExtBaseVector limb_widths_match_modulus.
@@ -156,13 +115,11 @@ Section PseudoMersenneProofs.
Proof.
intros.
replace (2^k) with ((2^k - c) + c) by ring.
- rewrite Z.mul_add_distr_r.
- rewrite Zplus_mod.
+ rewrite Z.mul_add_distr_r, Zplus_mod.
unfold c.
rewrite Z.sub_sub_distr, Z.sub_diag.
simpl.
- rewrite Z.mul_comm.
- rewrite Z.mod_add_l; auto using modulus_nonzero.
+ rewrite Z.mul_comm, Z.mod_add_l; auto using modulus_nonzero.
rewrite <- Zplus_mod; auto.
Qed.
@@ -189,53 +146,24 @@ Section PseudoMersenneProofs.
BaseSystem.decode base (reduce us) mod modulus =
BaseSystem.decode (ext_base limb_widths) us mod modulus.
Proof.
- intros.
- rewrite extended_shiftadd.
- rewrite pseudomersenne_add.
- unfold reduce.
- remember (firstn (length base) us) as low.
- remember (skipn (length base) us) as high.
- unfold BaseSystem.decode.
- rewrite BaseSystemProofs.add_rep.
- replace (map (Z.mul c) high) with (BaseSystem.mul_each c high) by auto.
+ cbv [reduce]; intros.
+ rewrite extended_shiftadd, base_length, pseudomersenne_add, BaseSystemProofs.add_rep.
+ change (map (Z.mul c)) with (BaseSystem.mul_each c).
rewrite mul_each_rep; auto.
Qed.
- Lemma reduce_length : forall us,
- (length base <= length us <= length (ext_base limb_widths))%nat ->
- (length (reduce us) = length base)%nat.
+ Lemma mul_rep : forall u v x y, u ~= x -> v ~= y -> mul u v ~= (x*y)%F.
Proof.
- rewrite extended_base_length.
- unfold reduce; intros.
- rewrite add_length_exact.
- rewrite map_length, firstn_length, skipn_length.
- rewrite Min.min_l by omega.
- apply Max.max_l; omega.
- Qed.
-
- Lemma length_mul : forall u v,
- length u = length base
- -> length v = length base
- -> length (u .* v) = length base.
- Proof.
- autounfold in *; unfold ModularBaseSystem.mul in *; intuition eauto.
- apply reduce_length.
- rewrite mul_length_exact, extended_base_length; try omega.
- destruct u; try congruence.
- pose proof limb_widths_nonnil.
- autorewrite with distr_length in *.
- destruct limb_widths; simpl in *; congruence.
- Qed.
-
- Lemma mul_rep : forall u v x y, u ~= x -> v ~= y -> u .* v ~= (x*y)%F.
- Proof.
- split; autounfold in *; unfold ModularBaseSystem.mul in *.
- { apply length_mul; intuition auto. }
- { intuition idtac; subst.
- rewrite ZToField_mod, reduce_rep, <-ZToField_mod.
- rewrite mul_rep by (auto using ExtBaseVector || rewrite extended_base_length; omega).
- rewrite 2decode_short by auto with omega.
- apply ZToField_mul. }
+ autounfold in *; unfold ModularBaseSystem.mul in *.
+ intuition idtac; subst.
+ rewrite to_list_from_list.
+ cbv [ModularBaseSystemList.mul ModularBaseSystemList.decode].
+ rewrite ZToField_mod, reduce_rep, <-ZToField_mod.
+ pose proof (@base_from_limb_widths_length limb_widths).
+ rewrite mul_rep by (auto using ExtBaseVector || rewrite extended_base_length, !length_to_list; omega).
+ rewrite 2decode_short by (rewrite ?base_from_limb_widths_length;
+ auto using Nat.eq_le_incl, length_to_list with omega).
+ apply ZToField_mul.
Qed.
Lemma nth_default_base_positive : forall i, (i < length base)%nat ->
@@ -259,11 +187,11 @@ Section PseudoMersenneProofs.
apply base_succ; eauto.
Qed.
- Lemma Fdecode_decode_mod : forall us x, (length us = length base) ->
- decode us = x -> BaseSystem.decode base us mod modulus = x.
+ Lemma Fdecode_decode_mod : forall us x,
+ decode us = x -> BaseSystem.decode base (to_list us) mod modulus = x.
Proof.
- unfold decode; intros ? ? ? decode_us.
- rewrite <-decode_us.
+ autounfold; intros.
+ rewrite <-H.
apply FieldToZ_ZToField.
Qed.
@@ -276,7 +204,7 @@ Section PseudoMersenneProofs.
intros ? ?; unfold carry_done; split; [ intros Hcarry_done i | intros Hbounds i i_lt ].
+ destruct (lt_dec i (length base)) as [i_lt | i_nlt].
- specialize (Hcarry_done i i_lt).
- split; [ intuition auto | ].
+ split; [ intuition | ].
destruct Hcarry_done as [Hnth_nonneg Hshiftr_0].
apply Z.shiftr_eq_0_iff in Hshiftr_0.
destruct Hshiftr_0 as [nth_0 | []]; [ rewrite nth_0; zero_bounds | ].
@@ -284,7 +212,7 @@ Section PseudoMersenneProofs.
- rewrite nth_default_out_of_bounds by omega.
split; zero_bounds.
+ specialize (Hbounds i).
- split; [ intuition auto | ].
+ split; [ intuition | ].
destruct Hbounds as [nth_nonneg nth_lt_pow2].
apply Z.shiftr_eq_0_iff.
apply Z.le_lteq in nth_nonneg; destruct nth_nonneg; try solve [left; auto].
@@ -292,31 +220,23 @@ Section PseudoMersenneProofs.
apply Z.log2_lt_pow2; auto.
Qed.
- Context mm (mm_length : length mm = length base) (mm_spec : decode mm = 0%F).
-
- Lemma length_sub : forall u v,
- length u = length base
- -> length v = length base
- -> length (ModularBaseSystem.sub mm u v) = length base.
- Proof.
- autounfold; unfold ModularBaseSystem.sub; intuition idtac.
- rewrite sub_length, add_length_exact.
- case_max; try rewrite Max.max_r; omega.
- Qed.
+ Context (mm : digits) (mm_spec : decode mm = 0%F).
Lemma sub_rep : forall u v x y, u ~= x -> v ~= y ->
ModularBaseSystem.sub mm u v ~= (x-y)%F.
Proof.
- split; autounfold in *.
- { apply length_sub; intuition (auto; omega). }
- { unfold decode, ModularBaseSystem.sub, BaseSystem.decode in *; intuition idtac.
- rewrite BaseSystemProofs.sub_rep, BaseSystemProofs.add_rep.
- rewrite ZToField_sub, ZToField_add.
- match goal with H : _ = 0%F |- _ => rewrite H end.
- rewrite F_add_0_l. congruence. }
+ autounfold; cbv [sub]; intros.
+ rewrite to_list_from_list; autounfold.
+ cbv [ModularBaseSystemList.sub].
+ rewrite BaseSystemProofs.sub_rep, BaseSystemProofs.add_rep.
+ rewrite ZToField_sub, ZToField_add, ZToField_mod.
+ apply Fdecode_decode_mod in mm_spec; cbv [BaseSystem.decode] in *.
+ rewrite mm_spec, F_add_0_l.
+ f_equal; assumption.
Qed.
End PseudoMersenneProofs.
+Opaque encode add mul sub.
Section CarryProofs.
Context `{prm : PseudoMersenneBaseParams}.
@@ -332,111 +252,69 @@ Section CarryProofs.
Hint Resolve base_length_lt_pred.
Lemma carry_decode_eq_reduce : forall us,
- (length us = length base) ->
+ (length us = length limb_widths) ->
BaseSystem.decode base (carry_and_reduce (pred (length base)) us) mod modulus
= BaseSystem.decode base us mod modulus.
Proof.
unfold carry_and_reduce; intros ? length_eq.
pose proof base_length_nonzero.
- rewrite add_to_nth_sum by (rewrite length_set_nth; omega).
- rewrite set_nth_sum by omega.
+ rewrite add_to_nth_sum by (rewrite length_set_nth, base_length; omega).
+ rewrite set_nth_sum by (rewrite base_length; omega).
rewrite Zplus_comm, <- Z.mul_assoc, <- pseudomersenne_add, BaseSystem.b0_1.
rewrite (Z.mul_comm (2 ^ k)), <- Zred_factor0.
f_equal.
rewrite <- (Z.add_comm (BaseSystem.decode base us)), <- Z.add_assoc, <- Z.add_0_r.
f_equal.
destruct (NPeano.Nat.eq_dec (length base) 0) as [length_zero | length_nonzero].
- + apply length0_nil in length_zero.
- pose proof (base_length) as limbs_length.
- rewrite length_zero in length_eq, limbs_length.
- apply length0_nil in length_eq.
- symmetry in limbs_length.
- apply length0_nil in limbs_length.
- subst; rewrite length_zero, limbs_length, nth_default_nil.
- reflexivity.
+ + pose proof (base_length) as limbs_length.
+ destruct us; rewrite ?(@nil_length0 Z), ?(@length_cons Z) in *;
+ pose proof base_length_nonzero; omega.
+ rewrite nth_default_base by (omega || eauto).
rewrite <- Z.add_opp_l, <- Z.opp_sub_distr.
unfold Z.pow2_mod.
rewrite Z.land_ones by eauto using log_cap_nonneg.
rewrite <- Z.mul_div_eq by (apply Z.gt_lt_iff; apply Z.pow_pos_nonneg; omega || eauto using log_cap_nonneg).
rewrite Z.shiftr_div_pow2 by eauto using log_cap_nonneg.
- rewrite Zopp_mult_distr_r.
- rewrite Z.mul_comm.
- rewrite Z.mul_assoc.
- rewrite <- Z.pow_add_r by eauto using log_cap_nonneg.
unfold k.
replace (length limb_widths) with (S (pred (length base))) by
(subst; rewrite <- base_length; apply NPeano.Nat.succ_pred; omega).
rewrite sum_firstn_succ with (x:= log_cap (pred (length base))) by
(apply nth_error_Some_nth_default; rewrite <- base_length; omega).
- rewrite <- Zopp_mult_distr_r.
- rewrite Z.mul_comm.
- rewrite (Z.add_comm (log_cap (pred (length base)))).
+ rewrite Z.pow_add_r by eauto using log_cap_nonneg.
ring.
Qed.
- Lemma length_carry_and_reduce : forall i us, length (carry_and_reduce i us) = length us.
- Proof. intros; unfold carry_and_reduce; autorewrite with distr_length; reflexivity. Qed.
- Hint Rewrite @length_carry_and_reduce : distr_length.
-
- Lemma length_carry : forall i us, length (carry i us) = length us.
- Proof. intros; unfold carry; break_if; autorewrite with distr_length; reflexivity. Qed.
- Hint Rewrite @length_carry : distr_length.
-
- Local Hint Extern 1 (length _ = _) => progress autorewrite with distr_length.
-
Lemma carry_rep : forall i us x,
- (length us = length base) ->
(i < length base)%nat ->
us ~= x -> carry i us ~= x.
Proof.
- pose proof length_carry. pose proof carry_decode_eq_reduce. pose proof (@carry_simple_decode_eq limb_widths).
+ cbv [carry rep decode]; intros.
+ rewrite to_list_from_list.
+ pose proof carry_decode_eq_reduce. pose proof (@carry_simple_decode_eq limb_widths).
+
specialize_by eauto.
- intros; split; try solve [ distr_length ].
- unfold rep, decode, carry in *.
- intuition auto; break_if; subst; eauto; apply F_eq; simpl; intuition auto with zarith.
+ cbv [ModularBaseSystemList.carry].
+ break_if; subst; eauto.
+ apply F_eq; apply carry_decode_eq_reduce; apply length_to_list.
+ cbv [ModularBaseSystemList.decode].
+ f_equal.
+ apply carry_simple_decode_eq; try omega; rewrite ?base_length; auto using length_to_list.
Qed.
Hint Resolve carry_rep.
- Lemma length_carry_sequence: forall is us,
- (length (carry_sequence is us) = length us)%nat.
- Proof.
- induction is; boring.
- Qed.
- Hint Rewrite length_carry_sequence : distr_length.
-
- Lemma carry_sequence_length: forall is us,
- (length us = length base)%nat ->
- (length (carry_sequence is us) = length base)%nat.
- Proof. intros; distr_length. Qed.
- Hint Resolve carry_sequence_length.
-
Lemma carry_sequence_rep : forall is us x,
(forall i, In i is -> (i < length base)%nat) ->
- (length us = length base) ->
us ~= x -> carry_sequence is us ~= x.
Proof.
induction is; boring.
Qed.
- Lemma length_carry_full : forall us,
- length (carry_full us) = length us.
- Proof.
- intros; cbv [carry_full]; auto using carry_sequence_length.
- Qed.
- Hint Rewrite length_carry_full : distr_length.
-
- Lemma carry_full_length : forall us, (length us = length base)%nat ->
- length (carry_full us) = length base.
- Proof. intros; distr_length. Qed.
-
Lemma carry_full_preserves_rep : forall us x,
rep us x -> rep (carry_full us) x.
Proof.
unfold carry_full; intros.
apply carry_sequence_rep; auto.
unfold full_carry_chain; rewrite base_length; apply make_chain_lt.
- eauto using rep_length.
Qed.
Opaque carry_full.
@@ -448,36 +326,9 @@ Section CarryProofs.
auto using mul_rep.
Qed.
- Local Arguments minus !_ !_.
-
- Lemma length_carry_mul : forall us vs,
- length (carry_mul us vs) = (if eq_nat_dec (length us) 0
- then 0
- else if le_dec (length base) (pred (length us + length vs))
- then if lt_dec (length base + length base) (pred (length us + length vs))
- then pred (length us + length vs) - length base
- else length base
- else pred (length us + length vs))%nat.
- Proof.
- unfold carry_mul, ModularBaseSystem.mul, reduce; intros; autorewrite with distr_length natsimplify.
- destruct us; simpl; autorewrite with natsimplify.
- { reflexivity. }
- { repeat break_if; omega *. }
- Qed.
-
- Lemma carry_mul_length : forall us vs,
- length us = length base -> length vs = length base ->
- length (carry_mul us vs) = length base.
- Proof.
- intros; rewrite length_carry_mul.
- rewrite_hyp !* in *.
- edestruct eq_nat_dec; [ congruence | ].
- autorewrite with natsimplify; reflexivity.
- Qed.
-
End CarryProofs.
-Hint Rewrite @length_carry_and_reduce @length_carry @length_carry_sequence @length_carry_full @length_carry_mul : distr_length.
+Hint Rewrite @length_carry_and_reduce @length_carry : distr_length.
Section CanonicalizationProofs.
Context `{prm : PseudoMersenneBaseParams}.
@@ -486,13 +337,13 @@ Section CanonicalizationProofs.
Context (lt_1_length_base : (1 < length base)%nat)
{B} (B_pos : 0 < B) (B_compat : forall w, In w limb_widths -> w <= B)
(* on the first reduce step, we add at most one bit of width to the first digit *)
- (c_reduce1 : c * (Z.ones (B - log_cap (pred (length base)))) < max_bound 0 + 1)
+ (c_reduce1 : c * (Z.ones (B - log_cap (pred (length base)))) < 2 ^ log_cap 0)
(* on the second reduce step, we add at most one bit of width to the first digit,
and leave room to carry c one more time after the highest bit is carried *)
- (c_reduce2 : c <= max_bound 0 - c)
+ (c_reduce2 : c <= nth_default 0 modulus_digits 0)
(* this condition is probably implied by c_reduce2, but is more straighforward to compute than to prove *)
(two_pow_k_le_2modulus : 2 ^ k <= 2 * modulus).
-
+(*
(* BEGIN groundwork proofs *)
Local Hint Resolve (@log_cap_nonneg limb_widths) limb_widths_nonneg.
@@ -502,20 +353,20 @@ Section CanonicalizationProofs.
Qed.
Local Hint Resolve pow_2_log_cap_pos.
- Lemma max_bound_log_cap : forall i, Z.succ (max_bound i) = 2 ^ log_cap i.
+ Lemma max_value_log_cap : forall i, Z.succ (max_value i) = 2 ^ log_cap i.
Proof.
intros.
- unfold max_bound, Z.ones.
+ unfold max_value, Z.ones.
rewrite Z.shiftl_1_l.
omega.
Qed.
- Lemma pow2_mod_log_cap_range : forall a i, 0 <= Z.pow2_mod a (log_cap i) <= max_bound i.
+ Lemma pow2_mod_log_cap_range : forall a i, 0 <= Z.pow2_mod a (log_cap i) <= max_value i.
Proof.
intros.
unfold Z.pow2_mod.
rewrite Z.land_ones by eauto using log_cap_nonneg.
- unfold max_bound, Z.ones.
+ unfold max_value, Z.ones.
rewrite Z.shiftl_1_l, <-Z.lt_le_pred.
apply Z_mod_lt.
pose proof (pow_2_log_cap_pos i).
@@ -528,13 +379,13 @@ Section CanonicalizationProofs.
pose proof (pow2_mod_log_cap_range a i); omega.
Qed.
- Lemma pow2_mod_log_cap_bounds_upper : forall a i, Z.pow2_mod a (log_cap i) <= max_bound i.
+ Lemma pow2_mod_log_cap_bounds_upper : forall a i, Z.pow2_mod a (log_cap i) <= max_value i.
Proof.
intros.
pose proof (pow2_mod_log_cap_range a i); omega.
Qed.
- Lemma pow2_mod_log_cap_small : forall a i, 0 <= a <= max_bound i ->
+ Lemma pow2_mod_log_cap_small : forall a i, 0 <= a <= max_value i ->
Z.pow2_mod a (log_cap i) = a.
Proof.
intros.
@@ -542,35 +393,35 @@ Section CanonicalizationProofs.
rewrite Z.land_ones by eauto using log_cap_nonneg.
apply Z.mod_small.
split; try omega.
- rewrite <- max_bound_log_cap.
+ rewrite <- max_value_log_cap.
omega.
Qed.
- Lemma max_bound_pos : forall i, (i < length base)%nat -> 0 < max_bound i.
+ Lemma max_value_pos : forall i, (i < length base)%nat -> 0 < max_value i.
Proof.
- unfold max_bound; intros; apply Z.ones_pos_pos.
+ unfold max_value; intros; apply Z.ones_pos_pos.
apply limb_widths_pos.
rewrite nth_default_eq.
apply nth_In.
rewrite <-base_length; assumption.
Qed.
- Local Hint Resolve max_bound_pos.
+ Local Hint Resolve max_value_pos.
- Lemma max_bound_nonneg : forall i, 0 <= max_bound i.
+ Lemma max_value_nonneg : forall i, 0 <= max_value i.
Proof.
- unfold max_bound; intros; eauto using Z.ones_nonneg.
+ unfold max_value; intros; eauto using Z.ones_nonneg.
Qed.
- Local Hint Resolve max_bound_nonneg.
+ Local Hint Resolve max_value_nonneg.
- Lemma shiftr_eq_0_max_bound : forall i a, Z.shiftr a (log_cap i) = 0 ->
- a <= max_bound i.
+ Lemma shiftr_eq_0_max_value : forall i a, Z.shiftr a (log_cap i) = 0 ->
+ a <= max_value i.
Proof.
intros ? ? shiftr_0.
apply Z.shiftr_eq_0_iff in shiftr_0.
- intuition auto; subst; try apply max_bound_nonneg.
+ intuition; subst; try apply max_value_nonneg.
match goal with H : Z.log2 _ < log_cap _ |- _ => apply Z.log2_lt_pow2 in H;
- replace (2 ^ log_cap i) with (Z.succ (max_bound i)) in H by
- (unfold max_bound, Z.ones; rewrite Z.shiftl_1_l; omega)
+ replace (2 ^ log_cap i) with (Z.succ (max_value i)) in H by
+ (unfold max_value, Z.ones; rewrite Z.shiftl_1_l; omega)
end; auto.
omega.
Qed.
@@ -589,16 +440,16 @@ Section CanonicalizationProofs.
Qed.
Local Hint Resolve B_compat_log_cap.
- Lemma max_bound_shiftr_eq_0 : forall i a, 0 <= a -> a <= max_bound i ->
+ Lemma max_value_shiftr_eq_0 : forall i a, 0 <= a -> a <= max_value i ->
Z.shiftr a (log_cap i) = 0.
Proof.
- intros ? ? ? le_max_bound.
+ intros ? ? ? le_max_value.
apply Z.shiftr_eq_0_iff.
destruct (Z_eq_dec a 0); auto.
right.
split; try omega.
apply Z.log2_lt_pow2; try omega.
- rewrite <-max_bound_log_cap.
+ rewrite <-max_value_log_cap.
omega.
Qed.
@@ -608,7 +459,7 @@ Section CanonicalizationProofs.
Qed.
(* END groundwork proofs *)
- Opaque Z.pow2_mod max_bound.
+ Opaque Z.pow2_mod max_value.
(* automation *)
Ltac carry_length_conditions' := unfold carry_full;
@@ -640,7 +491,7 @@ Section CanonicalizationProofs.
(* BEGIN proofs about first carry loop *)
Lemma nth_default_carry_bound_upper : forall i us, (length us = length base) ->
- nth_default 0 (carry i us) i <= max_bound i.
+ nth_default 0 (carry i us) i <= max_value i.
Proof.
unfold carry; intros.
break_if.
@@ -707,7 +558,7 @@ Section CanonicalizationProofs.
Lemma carry_nothing : forall i j us, (i < length base)%nat ->
(length us = length base)%nat ->
- 0 <= nth_default 0 us j <= max_bound j ->
+ 0 <= nth_default 0 us j <= max_value j ->
nth_default 0 (carry j us) i = nth_default 0 us i.
Proof.
unfold carry, carry_and_reduce; intros.
@@ -717,7 +568,7 @@ Section CanonicalizationProofs.
|| omega).
Qed.
- Hint Rewrite pow2_mod_log_cap_small using (intuition auto; auto using shiftr_eq_0_max_bound) : core.
+ Hint Rewrite pow2_mod_log_cap_small using (intuition; auto using shiftr_eq_0_max_bound) : core.
Lemma carry_carry_done_done : forall i us,
(length us = length base)%nat ->
@@ -730,13 +581,13 @@ Section CanonicalizationProofs.
split.
+ rewrite carry_nothing; auto.
split; [ apply Hcarry_done; auto | ].
- apply shiftr_eq_0_max_bound.
+ apply shiftr_eq_0_max_value.
apply Hcarry_done; auto.
+ unfold carry, carry_and_reduce; break_if; subst.
- add_set_nth; subst.
* rewrite shiftr_0_i, Z.mul_0_r, Z.add_0_l.
assumption.
- * rewrite pow2_mod_log_cap_small by (intuition auto; auto using shiftr_eq_0_max_bound).
+ * rewrite pow2_mod_log_cap_small by (intuition; auto using shiftr_eq_0_max_value).
assumption.
- repeat (carry_length_conditions
|| (autorewrite with push_nth_default natsimplify core zsimplify)
@@ -753,7 +604,7 @@ Section CanonicalizationProofs.
Lemma carry_bounds_0_upper : forall us j, (length us = length base) ->
(0 < j < length base)%nat ->
- nth_default 0 (carry_sequence (make_chain j) us) 0 <= max_bound 0.
+ nth_default 0 (carry_sequence (make_chain j) us) 0 <= max_value 0.
Proof.
induction j as [ | [ | j ] IHj ]; [simpl; intros; omega | | ]; intros.
+ subst; simpl; auto.
@@ -761,7 +612,7 @@ Section CanonicalizationProofs.
Qed.
Lemma carry_bounds_upper : forall i us j, (0 < i < j)%nat -> (length us = length base) ->
- nth_default 0 (carry_sequence (make_chain j) us) i <= max_bound i.
+ nth_default 0 (carry_sequence (make_chain j) us) i <= max_value i.
Proof.
unfold carry_sequence;
induction j; [simpl; intros; omega | ].
@@ -840,7 +691,7 @@ Section CanonicalizationProofs.
Lemma carry_full_bounds : forall us i, (i <> 0)%nat -> (forall i, 0 <= nth_default 0 us i) ->
(length us = length base)%nat ->
- 0 <= nth_default 0 (carry_full us) i <= max_bound i.
+ 0 <= nth_default 0 (carry_full us) i <= max_value i.
Proof.
unfold carry_full, full_carry_chain; intros.
split; (destruct (lt_dec i (length limb_widths));
@@ -878,13 +729,13 @@ Section CanonicalizationProofs.
intros ? ? PCB ?.
induction i.
+ simpl. specialize (PCB 0%nat).
- intuition auto.
+ intuition.
+ simpl.
destruct (lt_eq_lt_dec i (pred (length base))) as [[? | ? ] | ? ].
- apply carry_simple_no_overflow; carry_length_conditions; carry_seq_lower_bound.
rewrite carry_sequence_unaffected; try omega.
specialize (PCB (S i)); rewrite Nat.pred_succ in PCB.
- break_if; intuition auto with zarith.
+ break_if; intuition.
- unfold carry; break_if; try omega.
rewrite nth_default_out_of_bounds; [ apply Z.pow_pos_nonneg; omega | ].
subst; unfold carry_and_reduce.
@@ -895,7 +746,7 @@ Section CanonicalizationProofs.
Lemma carry_full_bounds_0 : forall us, pre_carry_bounds us ->
(length us = length base)%nat ->
- 0 <= nth_default 0 (carry_full us) 0 <= max_bound 0 + c * (Z.ones (B - log_cap (pred (length base)))).
+ 0 <= nth_default 0 (carry_full us) 0 <= max_value 0 + c * (Z.ones (B - log_cap (pred (length base)))).
Proof.
unfold carry_full, full_carry_chain; intros.
rewrite <- base_length.
@@ -945,7 +796,7 @@ Section CanonicalizationProofs.
- apply IHi; auto; omega.
- rewrite carry_sequence_unaffected by carry_length_conditions.
apply carry_full_bounds; auto; omega.
- + rewrite <-max_bound_log_cap, <-Z.add_1_l.
+ + rewrite <-max_value_log_cap, <-Z.add_1_l.
apply Z.add_le_mono.
- rewrite Z.shiftr_div_pow2 by eauto using log_cap_nonneg.
apply Z.div_floor; auto.
@@ -953,7 +804,7 @@ Section CanonicalizationProofs.
* simpl.
eapply Z.le_lt_trans; [ apply carry_full_bounds_0; auto | ].
replace (2 ^ log_cap 0 * 2) with (2 ^ log_cap 0 + 2 ^ log_cap 0) by ring.
- rewrite <-max_bound_log_cap, <-Z.add_1_l.
+ rewrite <-max_value_log_cap, <-Z.add_1_l.
apply Z.add_lt_le_mono; omega.
* eapply Z.le_lt_trans; [ apply IHi; auto; omega | ].
apply Z.lt_mul_diag_r; auto; omega.
@@ -963,7 +814,7 @@ Section CanonicalizationProofs.
Lemma carry_full_2_bounds_0 : forall us, pre_carry_bounds us ->
(length us = length base)%nat -> (1 < length base)%nat ->
- 0 <= nth_default 0 (carry_full (carry_full us)) 0 <= max_bound 0 + c.
+ 0 <= nth_default 0 (carry_full (carry_full us)) 0 <= max_value 0 + c.
Proof.
intros.
unfold carry_full at 1 3, full_carry_chain.
@@ -1005,7 +856,7 @@ Section CanonicalizationProofs.
rewrite carry_sequence_unaffected by carry_length_conditions.
apply carry_full_bounds; carry_length_conditions.
carry_seq_lower_bound.
- + rewrite <-max_bound_log_cap, <-Z.add_1_l.
+ + rewrite <-max_value_log_cap, <-Z.add_1_l.
rewrite Z.shiftr_div_pow2 by eauto using log_cap_nonneg.
apply Z.add_le_mono.
- apply Z.div_le_upper_bound; auto.
@@ -1031,20 +882,20 @@ Section CanonicalizationProofs.
- eapply carry_full_2_bounds_0; eauto.
- eapply carry_full_bounds; eauto; carry_length_conditions.
carry_seq_lower_bound.
- + rewrite <-max_bound_log_cap, <-Z.add_1_l.
+ + rewrite <-max_value_log_cap, <-Z.add_1_l.
rewrite Z.shiftr_div_pow2 by eauto using log_cap_nonneg.
apply Z.add_le_mono.
- apply Z.div_floor; auto.
eapply Z.le_lt_trans; [ eapply carry_full_2_bounds_0; eauto | ].
replace (Z.succ 1) with (2 ^ 1) by ring.
- rewrite <-max_bound_log_cap.
+ rewrite <-max_value_log_cap.
ring_simplify. pose proof c_pos; omega.
- apply carry_full_bounds; carry_length_conditions; carry_seq_lower_bound.
Qed.
Lemma carry_full_2_bounds' : forall us i j, pre_carry_bounds us ->
(length us = length base)%nat -> (0 < i < length base)%nat -> (i + j < length base)%nat -> (j <> 0)%nat ->
- 0 <= nth_default 0 (carry_sequence (make_chain (i + j)) (carry_full (carry_full us))) i <= max_bound i.
+ 0 <= nth_default 0 (carry_sequence (make_chain (i + j)) (carry_full (carry_full us))) i <= max_value i.
Proof.
induction j; intros; try omega.
split; (destruct j; [ rewrite Nat.add_1_r; simpl
@@ -1055,7 +906,7 @@ Section CanonicalizationProofs.
Lemma carry_full_2_bounds : forall us i j, pre_carry_bounds us ->
(length us = length base)%nat -> (0 < i < length base)%nat -> (i < j < length base)%nat ->
- 0 <= nth_default 0 (carry_sequence (make_chain j) (carry_full (carry_full us))) i <= max_bound i.
+ 0 <= nth_default 0 (carry_sequence (make_chain j) (carry_full (carry_full us))) i <= max_value i.
Proof.
intros.
replace j with (i + (j - i))%nat by omega.
@@ -1077,7 +928,7 @@ Section CanonicalizationProofs.
apply pow2_mod_log_cap_bounds_lower.
+ rewrite carry_unaffected_low by carry_length_conditions.
assert (0 < S i < length base)%nat by omega.
- intuition auto.
+ intuition.
Qed.
Lemma carry_full_2_bounds_lower :forall us i, pre_carry_bounds us ->
@@ -1096,20 +947,20 @@ Section CanonicalizationProofs.
Lemma carry_carry_full_2_bounds_0_upper : forall us i, pre_carry_bounds us ->
(length us = length base)%nat -> (0 < i < length base)%nat ->
- (nth_default 0 (carry_sequence (make_chain i) (carry_full (carry_full us))) 0 <= max_bound 0 - c)
+ (nth_default 0 (carry_sequence (make_chain i) (carry_full (carry_full us))) 0 <= max_value 0 - c)
\/ carry_done (carry_sequence (make_chain i) (carry_full (carry_full us))).
Proof.
induction i; try omega.
intros ? length_eq ?; simpl.
destruct i.
- + destruct (Z_le_dec (nth_default 0 (carry_full (carry_full us)) 0) (max_bound 0)).
+ + destruct (Z_le_dec (nth_default 0 (carry_full (carry_full us)) 0) (max_value 0)).
- right.
apply carry_carry_done_done; try solve [carry_length_conditions].
apply carry_done_bounds; try solve [carry_length_conditions].
intros.
simpl.
split; [ auto using carry_full_2_bounds_lower | ].
- destruct i; rewrite <-max_bound_log_cap, Z.lt_succ_r; auto.
+ destruct i; rewrite <-max_value_log_cap, Z.lt_succ_r; auto.
apply carry_full_bounds; auto using carry_full_bounds_lower.
- left; unfold carry.
break_if;
@@ -1117,21 +968,21 @@ Section CanonicalizationProofs.
autorewrite with push_nth_default natsimplify.
simpl.
remember ((nth_default 0 (carry_full (carry_full us)) 0)) as x.
- apply Z.le_trans with (m := (max_bound 0 + c) - (1 + max_bound 0)); try omega.
+ apply Z.le_trans with (m := (max_value 0 + c) - (1 + max_value 0)); try omega.
replace x with ((x - 2 ^ log_cap 0) + (1 * 2 ^ log_cap 0)) by ring.
rewrite Z.pow2_mod_spec by eauto.
cbv [make_chain carry_sequence fold_right].
rewrite Z.mod_add by (pose proof (pow_2_log_cap_pos 0); omega).
- rewrite <-max_bound_log_cap, <-Z.add_1_l, Z.mod_small;
+ rewrite <-max_value_log_cap, <-Z.add_1_l, Z.mod_small;
[ apply Z.sub_le_mono_r; subst; apply carry_full_2_bounds_0; auto | ].
split; try omega.
pose proof carry_full_2_bounds_0.
- apply Z.le_lt_trans with (m := (max_bound 0 + c) - (1 + max_bound 0));
+ apply Z.le_lt_trans with (m := (max_value 0 + c) - (1 + max_value 0));
[ apply Z.sub_le_mono_r; subst x; apply carry_full_2_bounds_0; auto;
ring_simplify | ]; pose proof c_pos; omega.
+ rewrite carry_unaffected_low by carry_length_conditions.
assert (0 < S i < length base)%nat by omega.
- intuition auto; right.
+ intuition; right.
apply carry_carry_done_done; try solve [carry_length_conditions].
assumption.
Qed.
@@ -1143,7 +994,7 @@ Section CanonicalizationProofs.
Lemma carry_full_3_bounds : forall us i, pre_carry_bounds us ->
(length us = length base)%nat ->(i < length base)%nat ->
- 0 <= nth_default 0 (carry_full (carry_full (carry_full us))) i <= max_bound i.
+ 0 <= nth_default 0 (carry_full (carry_full (carry_full us))) i <= max_value i.
Proof.
intros.
destruct i; [ | apply carry_full_bounds; carry_length_conditions;
@@ -1162,8 +1013,8 @@ Section CanonicalizationProofs.
- eapply carry_carry_full_2_bounds_0_lower; eauto; omega.
+ pose proof (carry_carry_full_2_bounds_0_upper us (pred (length base))).
assert (0 < pred (length base) < length base)%nat by omega.
- intuition auto.
- - replace (max_bound 0) with (c + (max_bound 0 - c)) by ring.
+ intuition.
+ - replace (max_value 0) with (c + (max_value 0 - c)) by ring.
apply Z.add_le_mono; try assumption.
etransitivity; [ | replace c with (c * 1) by ring; reflexivity ].
apply Z.mul_le_mono_pos_l; try omega.
@@ -1175,7 +1026,7 @@ Section CanonicalizationProofs.
H : carry_done _ |- _ =>
destruct (H (pred (length base)) H0) as [Hcd1 Hcd2]; rewrite Hcd2 by omega end.
ring_simplify.
- apply shiftr_eq_0_max_bound; auto.
+ apply shiftr_eq_0_max_value; auto.
assert (0 < length base)%nat as zero_lt_length by omega.
match goal with H : carry_done _ |- _ =>
destruct (H 0%nat zero_lt_length) end.
@@ -1189,7 +1040,7 @@ Section CanonicalizationProofs.
intros.
apply carry_done_bounds; [ carry_length_conditions | intros ].
destruct (lt_dec i (length base)).
- + rewrite <-max_bound_log_cap, Z.lt_succ_r.
+ + rewrite <-max_value_log_cap, Z.lt_succ_r.
auto using carry_full_3_bounds.
+ rewrite nth_default_out_of_bounds; carry_length_conditions.
Qed.
@@ -1202,7 +1053,7 @@ Section CanonicalizationProofs.
Qed.
Lemma isFull'_last : forall us b j, (j <> 0)%nat -> isFull' us b j = true ->
- max_bound j = nth_default 0 us j.
+ max_value j = nth_default 0 us j.
Proof.
induction j; simpl; intros; try omega.
match goal with
@@ -1213,7 +1064,7 @@ Section CanonicalizationProofs.
Qed.
Lemma isFull'_lower_bound_0 : forall j us b, isFull' us b j = true ->
- max_bound 0 - c < nth_default 0 us 0.
+ max_value 0 - c < nth_default 0 us 0.
Proof.
induction j; intros.
+ match goal with H : isFull' _ _ 0 = _ |- _ => cbv [isFull'] in H;
@@ -1223,7 +1074,7 @@ Section CanonicalizationProofs.
Qed.
Lemma isFull'_true_full : forall us i j b, (i <> 0)%nat -> (i <= j)%nat -> isFull' us b j = true ->
- max_bound i = nth_default 0 us i.
+ max_value i = nth_default 0 us i.
Proof.
induction j; intros; try omega.
assert (i = S j \/ i <= j)%nat as cases by omega.
@@ -1266,23 +1117,23 @@ Section CanonicalizationProofs.
Qed.
Lemma full_isFull'_true : forall j us, (length us = length base) ->
- ( max_bound 0 - c < nth_default 0 us 0
- /\ (forall i, (0 < i <= j)%nat -> nth_default 0 us i = max_bound i)) ->
+ ( max_value 0 - c < nth_default 0 us 0
+ /\ (forall i, (0 < i <= j)%nat -> nth_default 0 us i = max_value i)) ->
isFull' us true j = true.
Proof.
induction j; intros.
+ cbv [isFull']; apply Bool.andb_true_iff.
- rewrite Z.ltb_lt; intuition auto.
- + intuition auto.
+ rewrite Z.ltb_lt; intuition.
+ + intuition.
simpl.
match goal with H : forall j, _ -> ?b j = ?a j |- appcontext[?a ?i =? ?b ?i] =>
replace (a i =? b i) with true by (symmetry; apply Z.eqb_eq; symmetry; apply H; omega) end.
- apply IHj; auto; intuition auto.
+ apply IHj; auto; intuition.
Qed.
Lemma isFull'_true_iff : forall j us, (length us = length base) -> (isFull' us true j = true <->
- max_bound 0 - c < nth_default 0 us 0
- /\ (forall i, (0 < i <= j)%nat -> nth_default 0 us i = max_bound i)).
+ max_value 0 - c < nth_default 0 us 0
+ /\ (forall i, (0 < i <= j)%nat -> nth_default 0 us i = max_value i)).
Proof.
intros; split; intros; auto using full_isFull'_true.
split; eauto using isFull'_lower_bound_0.
@@ -1295,7 +1146,7 @@ Section CanonicalizationProofs.
isFull' us true j = true.
Proof.
simpl; intros ? ? succ_true.
- destruct (max_bound (S j) =? nth_default 0 us (S j)); auto.
+ destruct (max_value (S j) =? nth_default 0 us (S j)); auto.
rewrite isFull'_false in succ_true.
congruence.
Qed.
@@ -1382,7 +1233,7 @@ Section CanonicalizationProofs.
replace 1 with (Z.succ 0) by reflexivity.
rewrite Z.le_succ_l, Z.lt_0_sub.
match goal with H : carry_done us |- _ => rewrite carry_done_bounds in H by auto; specialize (H n) end.
- replace x with (log_cap n); try intuition auto.
+ replace x with (log_cap n); try intuition.
apply nth_error_value_eq_nth_default; auto.
+ repeat erewrite firstn_all_strong by omega.
rewrite sum_firstn_all_succ by (rewrite <-base_length; omega).
@@ -1411,7 +1262,7 @@ Section CanonicalizationProofs.
- rewrite nth_default_base by (omega || eauto).
apply Z.pow_nonneg; omega.
- match goal with H : carry_done us |- _ => rewrite carry_done_bounds in H by auto; specialize (H n) end.
- intuition auto.
+ intuition.
+ eapply Z.le_trans; [ apply IHn; eauto | ].
repeat rewrite firstn_all_strong by omega.
omega.
@@ -1430,7 +1281,7 @@ Section CanonicalizationProofs.
Lemma nth_default_modulus_digits' : forall d j i,
nth_default d (modulus_digits' j) i =
if lt_dec i (S j)
- then (if (eq_nat_dec i 0) then max_bound i - c + 1 else max_bound i)
+ then (if (eq_nat_dec i 0) then max_value i - c + 1 else max_value i)
else d.
Proof.
induction j; intros; (break_if; [| apply nth_default_out_of_bounds; rewrite modulus_digits'_length; omega]).
@@ -1448,7 +1299,7 @@ Section CanonicalizationProofs.
Lemma nth_default_modulus_digits : forall d i,
nth_default d modulus_digits i =
if lt_dec i (length base)
- then (if (eq_nat_dec i 0) then max_bound i - c + 1 else max_bound i)
+ then (if (eq_nat_dec i 0) then max_value i - c + 1 else max_value i)
else d.
Proof.
unfold modulus_digits; intros.
@@ -1463,7 +1314,7 @@ Section CanonicalizationProofs.
intros.
rewrite nth_default_modulus_digits.
break_if; [ | split; auto; omega].
- break_if; subst; split; auto; try rewrite <- max_bound_log_cap; pose proof c_pos; omega.
+ break_if; subst; split; auto; try rewrite <- max_value_log_cap; pose proof c_pos; omega.
Qed.
Local Hint Resolve carry_done_modulus_digits.
@@ -1507,8 +1358,8 @@ Section CanonicalizationProofs.
rewrite decode'_cons, decode_nil, Z.add_0_r.
replace z with (nth_default 0 base 0) by (rewrite base_eq; auto).
rewrite nth_default_base by (omega || eauto).
- replace (max_bound 0 - c + 1) with (Z.succ (max_bound 0) - c) by ring.
- rewrite max_bound_log_cap.
+ replace (max_value 0 - c + 1) with (Z.succ (max_value 0) - c) by ring.
+ rewrite max_value_log_cap.
rewrite sum_firstn_succ with (x := log_cap 0) by (
apply nth_error_Some_nth_default; rewrite <-base_length; omega).
rewrite Z.pow_add_r by eauto.
@@ -1519,7 +1370,7 @@ Section CanonicalizationProofs.
- rewrite sum_firstn_succ with (x := log_cap (S i)) by
(apply nth_error_Some_nth_default;
rewrite <-base_length; omega).
- rewrite Z.pow_add_r, <-max_bound_log_cap, set_higher by eauto.
+ rewrite Z.pow_add_r, <-max_value_log_cap, set_higher by eauto.
rewrite IHi, modulus_digits'_length by omega.
rewrite nth_default_base by (omega || eauto).
ring.
@@ -1546,14 +1397,14 @@ Section CanonicalizationProofs.
+ cbv [modulus_digits' map].
f_equal.
apply land_max_ones_noop with (i := 0%nat).
- rewrite <-max_bound_log_cap.
+ rewrite <-max_value_log_cap.
pose proof c_pos; omega.
+ unfold modulus_digits'; fold modulus_digits'.
rewrite map_app.
f_equal; [ apply IHi; omega | ].
cbv [map]; f_equal.
apply land_max_ones_noop with (i := S i).
- rewrite <-max_bound_log_cap.
+ rewrite <-max_value_log_cap.
split; auto; omega.
Qed.
@@ -1580,7 +1431,7 @@ Section CanonicalizationProofs.
Lemma freeze_preserves_rep : forall us x, rep us x -> rep (freeze us) x.
Proof.
unfold rep; intros.
- intuition auto; rewrite ?freeze_length; auto.
+ intuition; rewrite ?freeze_length; auto.
unfold freeze, and_term.
break_if.
+ apply decode_mod with (us := carry_full (carry_full (carry_full us))).
@@ -1589,7 +1440,7 @@ Section CanonicalizationProofs.
apply Min.min_r.
simpl_lengths; omega.
- repeat apply carry_full_preserves_rep; repeat rewrite carry_full_length; auto.
- unfold rep; intuition auto.
+ unfold rep; intuition.
- rewrite decode_map2_sub by (simpl_lengths; omega).
rewrite map_land_max_ones_modulus_digits.
rewrite decode_modulus_digits.
@@ -1608,8 +1459,8 @@ Section CanonicalizationProofs.
Hint Resolve freeze_preserves_rep.
Lemma isFull_true_iff : forall us, (length us = length base) -> (isFull us = true <->
- max_bound 0 - c < nth_default 0 us 0
- /\ (forall i, (0 < i <= length base - 1)%nat -> nth_default 0 us i = max_bound i)).
+ max_value 0 - c < nth_default 0 us 0
+ /\ (forall i, (0 < i <= length base - 1)%nat -> nth_default 0 us i = max_value i)).
Proof.
unfold isFull; intros; auto using isFull'_true_iff.
Qed.
@@ -1882,8 +1733,8 @@ Section CanonicalizationProofs.
apply Z.compare_ge_iff.
omega.
* match goal with H : isFull' _ _ _ = true |- _ =>
- apply isFull'_true_iff in H; try assumption; destruct H as [? eq_max_bound] end.
- specialize (eq_max_bound j).
+ apply isFull'_true_iff in H; try assumption; destruct H as [? eq_max_value] end.
+ specialize (eq_max_value j).
omega.
+ apply isFull'_true_iff; try assumption.
match goal with H : compare' _ _ _ <> Lt |- _ => apply compare'_not_Lt in H; [ destruct H as [Hdigit0 Hnonzero] | | ] end.
@@ -1895,8 +1746,8 @@ Section CanonicalizationProofs.
- intros.
rewrite nth_default_modulus_digits.
repeat (break_if; try omega).
- rewrite <-Z.lt_succ_r with (m := max_bound i).
- rewrite max_bound_log_cap; apply carry_done_bounds; assumption.
+ rewrite <-Z.lt_succ_r with (m := max_value i).
+ rewrite max_value_log_cap; apply carry_done_bounds; assumption.
Qed.
Lemma isFull_compare : forall us, (length us = length base) -> carry_done us ->
@@ -1966,7 +1817,7 @@ Section CanonicalizationProofs.
specialize (high_digits i i_range).
clear first_digit i_range.
rewrite high_digits.
- rewrite <-max_bound_log_cap.
+ rewrite <-max_value_log_cap.
rewrite nth_default_modulus_digits.
repeat (break_if; try omega).
* rewrite Z.sub_diag.
@@ -2008,7 +1859,7 @@ Section CanonicalizationProofs.
(BaseSystem.decode base us) mod modulus = (BaseSystem.decode base vs) mod modulus.
Proof.
unfold rep, decode; intros.
- intuition auto.
+ intuition.
repeat rewrite <-FieldToZ_ZToField.
congruence.
Qed.
@@ -2024,7 +1875,7 @@ Section CanonicalizationProofs.
repeat match goal with Hmin : minimal_rep ?us |- _ => unfold minimal_rep in Hmin;
rewrite <- Hmin in eqmod; clear Hmin end.
apply Z.compare_eq_iff in eqmod.
- rewrite decode_compare in eqmod; unfold rep in *; auto; intuition auto; try congruence.
+ rewrite decode_compare in eqmod; unfold rep in *; auto; intuition; try congruence.
apply compare_Eq; auto.
congruence.
Qed.
@@ -2035,9 +1886,9 @@ Section CanonicalizationProofs.
freeze us = freeze vs.
Proof.
intros.
- assert (length us = length base) by (unfold rep in *; intuition auto).
- assert (length vs = length base) by (unfold rep in *; intuition auto).
+ assert (length us = length base) by (unfold rep in *; intuition).
+ assert (length vs = length base) by (unfold rep in *; intuition).
eapply minimal_rep_unique; eauto; rewrite freeze_length; assumption.
Qed.
-
+*)
End CanonicalizationProofs.
diff --git a/src/ModularArithmetic/Pow2Base.v b/src/ModularArithmetic/Pow2Base.v
index acc96ad73..c23cf8f40 100644
--- a/src/ModularArithmetic/Pow2Base.v
+++ b/src/ModularArithmetic/Pow2Base.v
@@ -39,7 +39,6 @@ Section Pow2Base.
encode' z i' ++ (Z.shiftr (Z.land z (Z.ones (lw i))) (lw i')) :: nil
end.
- (* max must be greater than input; this is used to truncate last digit *)
Definition encodeZ x:= encode' x (length limb_widths).
(** ** Carrying *)
diff --git a/src/ModularArithmetic/Pow2BaseProofs.v b/src/ModularArithmetic/Pow2BaseProofs.v
index d95de5bd1..78c6bba0f 100644
--- a/src/ModularArithmetic/Pow2BaseProofs.v
+++ b/src/ModularArithmetic/Pow2BaseProofs.v
@@ -230,10 +230,10 @@ Section BitwiseDecodeEncode.
Local Hint Resolve limb_widths_nonneg.
Local Notation "w[ i ]" := (nth_default 0 limb_widths i).
Local Notation base := (base_from_limb_widths limb_widths).
- Local Notation max := (upper_bound limb_widths).
+ Local Notation upper_bound := (upper_bound limb_widths).
Lemma encode'_spec : forall x i, (i <= length base)%nat ->
- encode' limb_widths x i = BaseSystem.encode' base x max i.
+ encode' limb_widths x i = BaseSystem.encode' base x upper_bound i.
Proof.
induction i; intros.
+ rewrite encode'_zero. reflexivity.
@@ -245,7 +245,7 @@ Section BitwiseDecodeEncode.
- repeat f_equal; rewrite nth_default_base by (omega || auto); reflexivity.
- repeat f_equal; try solve [rewrite nth_default_base by (omega || auto); reflexivity].
rewrite nth_default_out_of_bounds by omega.
- unfold upper_bound.
+ unfold Pow2Base.upper_bound.
rewrite <-base_from_limb_widths_length by auto.
congruence.
Qed.
@@ -255,7 +255,7 @@ Section BitwiseDecodeEncode.
intros; apply nth_default_preserves_properties; auto; omega.
Qed. Hint Resolve nth_default_limb_widths_nonneg.
- Lemma base_upper_bound_compatible : @base_max_succ_divide base max.
+ Lemma base_upper_bound_compatible : @base_max_succ_divide base upper_bound.
Proof.
unfold base_max_succ_divide; intros i lt_Si_length.
rewrite Nat.lt_eq_cases in lt_Si_length; destruct lt_Si_length;
@@ -265,7 +265,7 @@ Section BitwiseDecodeEncode.
rewrite Z.pow_add_r; auto using sum_firstn_limb_widths_nonneg.
apply Z.divide_factor_r.
+ rewrite nth_default_out_of_bounds by omega.
- unfold upper_bound.
+ unfold Pow2Base.upper_bound.
replace (length limb_widths) with (S (pred (length limb_widths))) by
(rewrite base_from_limb_widths_length in H by auto; omega).
replace i with (pred (length limb_widths)) by
@@ -278,12 +278,12 @@ Section BitwiseDecodeEncode.
Hint Resolve base_upper_bound_compatible.
Lemma encodeZ_spec : forall x,
- BaseSystem.decode base (encodeZ limb_widths x) = x mod max.
+ BaseSystem.decode base (encodeZ limb_widths x) = x mod upper_bound.
Proof.
intros.
assert (length base = length limb_widths) by auto using base_from_limb_widths_length.
unfold encodeZ; rewrite encode'_spec by omega.
- rewrite BaseSystemProofs.encode'_spec; unfold upper_bound; try zero_bounds;
+ rewrite BaseSystemProofs.encode'_spec; unfold Pow2Base.upper_bound; try zero_bounds;
auto using sum_firstn_limb_widths_nonneg.
rewrite nth_default_out_of_bounds by omega.
reflexivity.
@@ -416,14 +416,14 @@ End BitwiseDecodeEncode.
Section Conversion.
Context {limb_widthsA} (limb_widthsA_nonneg : forall w, In w limb_widthsA -> 0 <= w)
{limb_widthsB} (limb_widthsB_nonneg : forall w, In w limb_widthsB -> 0 <= w).
- Local Notation "{baseA}" := (base_from_limb_widths limb_widthsA).
- Local Notation "{baseB}" := (base_from_limb_widths limb_widthsB).
- Context (bvB : BaseSystem.BaseVector {baseB}).
+ Local Notation baseA := (base_from_limb_widths limb_widthsA).
+ Local Notation baseB := (base_from_limb_widths limb_widthsB).
+ Context (bvB : BaseSystem.BaseVector baseB).
Definition convert xs := @encodeZ limb_widthsB (@decode_bitwise limb_widthsA xs).
Lemma convert_spec : forall xs, @bounded limb_widthsA xs -> length xs = length limb_widthsA ->
- BaseSystem.decode {baseA} xs mod (@upper_bound limb_widthsB) = BaseSystem.decode {baseB} (convert xs).
+ BaseSystem.decode baseA xs mod (@upper_bound limb_widthsB) = BaseSystem.decode baseB (convert xs).
Proof.
unfold convert; intros.
rewrite encodeZ_spec, decode_bitwise_spec by auto.
diff --git a/src/Specific/GF1305.v b/src/Specific/GF1305.v
index 077c98954..fba77a4a8 100644
--- a/src/Specific/GF1305.v
+++ b/src/Specific/GF1305.v
@@ -1,13 +1,15 @@
-Require Import Crypto.ModularArithmetic.ModularBaseSystem.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
+Require Import Crypto.BaseSystem.
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystem.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemField.
Require Import Coq.Lists.List Crypto.Util.ListUtil.
-Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemInterface.
Require Import Crypto.Tactics.VerdiTactics.
-Require Import Crypto.BaseSystem.
Require Import Crypto.Util.ZUtil.
+Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Notations.
Require Import Crypto.Algebra.
Import ListNotations.
@@ -26,12 +28,13 @@ Instance params1305 : PseudoMersenneBaseParams modulus.
construct_params prime_modulus 5%nat 130.
Defined.
-Definition mul2modulus := Eval compute in (construct_mul2modulus params1305).
+Definition fe1305 := Eval compute in (tuple Z (length limb_widths)).
+
+Definition mul2modulus : fe1305 :=
+ Eval compute in (from_list_default 0%Z (length limb_widths) (construct_mul2modulus params1305)).
Instance subCoeff : SubtractionCoefficient modulus params1305.
apply Build_SubtractionCoefficient with (coeff := mul2modulus).
- cbv; auto.
- cbv [ModularBaseSystem.decode].
apply ZToField_eqmod.
cbv; reflexivity.
Defined.
@@ -49,9 +52,7 @@ Definition c_ := Eval compute in c.
Definition k_subst : k = k_ := eq_refl k_.
Definition c_subst : c = c_ := eq_refl c_.
-Definition fe1305 : Type := Eval cbv in fe.
-
-Local Opaque Z.shiftr Z.shiftl Z.land Z.mul Z.add Z.sub Let_In phi.
+Local Opaque Z.shiftr Z.shiftl Z.land Z.mul Z.add Z.sub Let_In.
Definition app_5 (f : fe1305) (P : fe1305 -> fe1305) : fe1305.
Proof.
@@ -80,25 +81,25 @@ Proof.
Qed.
Definition add_sig (f g : fe1305) :
- { fg : fe1305 | fg = ModularBaseSystemInterface.add f g}.
+ { fg : fe1305 | fg = add_opt f g}.
Proof.
eexists.
- rewrite <-appify2_correct. (* Coq 8.4 : 6s *)
+ rewrite <-appify2_correct.
cbv.
reflexivity.
-Defined. (* Coq 8.4 : 7s *)
+Defined.
Definition add (f g : fe1305) : fe1305 :=
Eval cbv beta iota delta [proj1_sig add_sig] in
proj1_sig (add_sig f g).
Definition add_correct (f g : fe1305)
- : add f g = ModularBaseSystemInterface.add f g :=
+ : add f g = add_opt f g :=
Eval cbv beta iota delta [proj1_sig add_sig] in
- proj2_sig (add_sig f g). (* Coq 8.4 : 10s *)
+ proj2_sig (add_sig f g).
Definition sub_sig (f g : fe1305) :
- { fg : fe1305 | fg = ModularBaseSystemInterface.sub f g}.
+ { fg : fe1305 | fg = sub_opt f g}.
Proof.
eexists.
rewrite <-appify2_correct.
@@ -111,12 +112,14 @@ Definition sub (f g : fe1305) : fe1305 :=
proj1_sig (sub_sig f g).
Definition sub_correct (f g : fe1305)
- : sub f g = ModularBaseSystemInterface.sub f g :=
+ : sub f g = sub_opt f g :=
Eval cbv beta iota delta [proj1_sig sub_sig] in
- proj2_sig (sub_sig f g). (* Coq 8.4 : 10s *)
+ proj2_sig (sub_sig f g).
+(* For multiplication, we add another layer of definition so that we can
+ rewrite under the [let] binders. *)
Definition mul_simpl_sig (f g : fe1305) :
- { fg : fe1305 | fg = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g}.
+ { fg : fe1305 | fg = carry_mul_opt k_ c_ f g}.
Proof.
cbv [fe1305] in *.
repeat match goal with p : (_ * Z)%type |- _ => destruct p end.
@@ -131,41 +134,40 @@ Definition mul_simpl (f g : fe1305) : fe1305 :=
proj1_sig (mul_simpl_sig f g).
Definition mul_simpl_correct (f g : fe1305)
- : mul_simpl f g = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g :=
+ : mul_simpl f g = carry_mul_opt k_ c_ f g :=
Eval cbv beta iota delta [proj1_sig mul_simpl_sig] in
proj2_sig (mul_simpl_sig f g).
Definition mul_sig (f g : fe1305) :
- { fg : fe1305 | fg = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g}.
+ { fg : fe1305 | fg = carry_mul_opt k_ c_ f g}.
Proof.
eexists.
rewrite <-mul_simpl_correct.
rewrite <-appify2_correct.
cbv.
- autorewrite with zsimplify.
reflexivity.
-Defined. (* Coq 8.4 : 14s *)
+Defined.
Definition mul (f g : fe1305) : fe1305 :=
Eval cbv beta iota delta [proj1_sig mul_sig] in
proj1_sig (mul_sig f g).
Definition mul_correct (f g : fe1305)
- : mul f g = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g :=
+ : mul f g = carry_mul_opt k_ c_ f g :=
Eval cbv beta iota delta [proj1_sig add_sig] in
- proj2_sig (mul_sig f g). (* Coq 8.4 : 5s *)
+ proj2_sig (mul_sig f g).
Import Morphisms.
-Lemma field1305 : @field fe eq zero one opp add sub mul inv div.
+Lemma field1305 : @field fe1305 eq zero one opp add sub mul inv div.
Proof.
pose proof (Equivalence_Reflexive : Reflexive eq).
- eapply (Field.equivalent_operations_field (fieldR := modular_base_system_field k_subst c_subst)).
+ eapply (Field.equivalent_operations_field (fieldR := modular_base_system_field k_ c_ k_subst c_subst)).
Grab Existential Variables.
+ reflexivity.
+ reflexivity.
+ reflexivity.
- + intros; rewrite mul_correct; reflexivity.
+ + intros; rewrite mul_correct. reflexivity.
+ intros; rewrite sub_correct; reflexivity.
+ intros; rewrite add_correct; reflexivity.
+ reflexivity.
diff --git a/src/Specific/GF25519.v b/src/Specific/GF25519.v
index 6298941db..7ece3a5da 100644
--- a/src/Specific/GF25519.v
+++ b/src/Specific/GF25519.v
@@ -1,16 +1,19 @@
-Require Import Crypto.ModularArithmetic.ModularBaseSystem.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
+Require Import Crypto.BaseSystem.
+Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystem.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemProofs.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemOpt.
+Require Import Crypto.ModularArithmetic.ModularBaseSystemField.
Require Import Coq.Lists.List Crypto.Util.ListUtil.
-Require Import Crypto.ModularArithmetic.PrimeFieldTheorems.
-Require Import Crypto.ModularArithmetic.ModularBaseSystemInterface.
Require Import Crypto.Tactics.VerdiTactics.
-Require Import Crypto.BaseSystem.
-Require Import Algebra.
+Require Import Crypto.Util.ZUtil.
+Require Import Crypto.Util.Tuple.
+Require Import Crypto.Util.Notations.
+Require Import Crypto.Algebra.
Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
-Require Import Crypto.Util.Notations.
Local Open Scope Z.
(* BEGIN PseudoMersenneBaseParams instance construction. *)
@@ -23,12 +26,13 @@ Instance params25519 : PseudoMersenneBaseParams modulus.
construct_params prime_modulus 10%nat 255.
Defined.
-Definition mul2modulus := Eval compute in (construct_mul2modulus params25519).
+Definition fe25519 := Eval compute in (tuple Z (length limb_widths)).
+
+Definition mul2modulus : fe25519 :=
+ Eval compute in (from_list_default 0%Z (length limb_widths) (construct_mul2modulus params25519)).
Instance subCoeff : SubtractionCoefficient modulus params25519.
apply Build_SubtractionCoefficient with (coeff := mul2modulus).
- cbv; auto.
- cbv [ModularBaseSystem.decode].
apply ZToField_eqmod.
cbv; reflexivity.
Defined.
@@ -45,11 +49,10 @@ Definition k_ := Eval compute in k.
Definition c_ := Eval compute in c.
Definition k_subst : k = k_ := eq_refl k_.
Definition c_subst : c = c_ := eq_refl c_.
-Definition fe25519 : Type := Eval cbv in fe.
Local Opaque Z.shiftr Z.shiftl Z.land Z.mul Z.add Z.sub Let_In.
-Definition app_10 (f : fe25519) (P : fe25519 -> fe25519) : fe25519.
+Definition app_5 (f : fe25519) (P : fe25519 -> fe25519) : fe25519.
Proof.
cbv [fe25519] in *.
set (f0 := f).
@@ -58,7 +61,7 @@ Proof.
apply f0.
Defined.
-Lemma app_10_correct : forall f P, app_10 f P = P f.
+Definition app_5_correct f (P : fe25519 -> fe25519) : app_5 f P = P f.
Proof.
intros.
cbv [fe25519] in *.
@@ -67,16 +70,16 @@ Proof.
Qed.
Definition appify2 (op : fe25519 -> fe25519 -> fe25519) (f g : fe25519):=
- app_10 f (fun f0 => (app_10 g (fun g0 => op f0 g0))).
+ app_5 f (fun f0 => (app_5 g (fun g0 => op f0 g0))).
Lemma appify2_correct : forall op f g, appify2 op f g = op f g.
Proof.
intros. cbv [appify2].
- etransitivity; apply app_10_correct.
+ etransitivity; apply app_5_correct.
Qed.
Definition add_sig (f g : fe25519) :
- { fg : fe25519 | fg = ModularBaseSystemInterface.add f g}.
+ { fg : fe25519 | fg = add_opt f g}.
Proof.
eexists.
rewrite <-appify2_correct.
@@ -89,12 +92,12 @@ Definition add (f g : fe25519) : fe25519 :=
proj1_sig (add_sig f g).
Definition add_correct (f g : fe25519)
- : add f g = ModularBaseSystemInterface.add f g :=
+ : add f g = add_opt f g :=
Eval cbv beta iota delta [proj1_sig add_sig] in
proj2_sig (add_sig f g).
Definition sub_sig (f g : fe25519) :
- { fg : fe25519 | fg = ModularBaseSystemInterface.sub f g}.
+ { fg : fe25519 | fg = sub_opt f g}.
Proof.
eexists.
rewrite <-appify2_correct.
@@ -107,12 +110,14 @@ Definition sub (f g : fe25519) : fe25519 :=
proj1_sig (sub_sig f g).
Definition sub_correct (f g : fe25519)
- : sub f g = ModularBaseSystemInterface.sub f g :=
+ : sub f g = sub_opt f g :=
Eval cbv beta iota delta [proj1_sig sub_sig] in
proj2_sig (sub_sig f g).
+(* For multiplication, we add another layer of definition so that we can
+ rewrite under the [let] binders. *)
Definition mul_simpl_sig (f g : fe25519) :
- { fg : fe25519 | fg = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g}.
+ { fg : fe25519 | fg = carry_mul_opt k_ c_ f g}.
Proof.
cbv [fe25519] in *.
repeat match goal with p : (_ * Z)%type |- _ => destruct p end.
@@ -127,15 +132,15 @@ Definition mul_simpl (f g : fe25519) : fe25519 :=
proj1_sig (mul_simpl_sig f g).
Definition mul_simpl_correct (f g : fe25519)
- : mul_simpl f g = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g :=
+ : mul_simpl f g = carry_mul_opt k_ c_ f g :=
Eval cbv beta iota delta [proj1_sig mul_simpl_sig] in
proj2_sig (mul_simpl_sig f g).
Definition mul_sig (f g : fe25519) :
- { fg : fe25519 | fg = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g}.
+ { fg : fe25519 | fg = carry_mul_opt k_ c_ f g}.
Proof.
eexists.
- rewrite <- mul_simpl_correct.
+ rewrite <-mul_simpl_correct.
rewrite <-appify2_correct.
cbv.
reflexivity.
@@ -146,8 +151,8 @@ Definition mul (f g : fe25519) : fe25519 :=
proj1_sig (mul_sig f g).
Definition mul_correct (f g : fe25519)
- : mul f g = ModularBaseSystemInterface.mul (k_ := k_) (c_ := c_) f g :=
- Eval cbv beta iota delta [proj1_sig mul_sig] in
+ : mul f g = carry_mul_opt k_ c_ f g :=
+ Eval cbv beta iota delta [proj1_sig add_sig] in
proj2_sig (mul_sig f g).
Import Morphisms.
@@ -155,12 +160,12 @@ Import Morphisms.
Lemma field25519 : @field fe25519 eq zero one opp add sub mul inv div.
Proof.
pose proof (Equivalence_Reflexive : Reflexive eq).
- eapply (Field.equivalent_operations_field (fieldR := modular_base_system_field k_subst c_subst)).
+ eapply (Field.equivalent_operations_field (fieldR := modular_base_system_field k_ c_ k_subst c_subst)).
Grab Existential Variables.
+ reflexivity.
+ reflexivity.
+ reflexivity.
- + intros; rewrite mul_correct; reflexivity.
+ + intros; rewrite mul_correct. reflexivity.
+ intros; rewrite sub_correct; reflexivity.
+ intros; rewrite add_correct; reflexivity.
+ reflexivity.