aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2018-12-19 18:03:20 -0500
committerGravatar Jason Gross <jasongross9@gmail.com>2018-12-20 14:21:37 -0500
commit578ed97d58d72810b9b41300d2b6012904ec4f95 (patch)
tree82d82f91c88e1b48d029118a4289fb26690d400c /src
parent96296137505331ebddddd1e17b4aed994f2118e7 (diff)
Remove glue admits in Toplevel1
After | File Name | Before || Change | % Change -------------------------------------------------------------------------------------------------------------------- 20m47.54s | Total | 20m48.81s || -0m01.26s | -0.10% -------------------------------------------------------------------------------------------------------------------- 3m14.11s | p384_32.c | 3m19.20s || -0m05.08s | -2.55% 6m18.53s | Experiments/NewPipeline/SlowPrimeSynthesisExamples.vo | 6m14.62s || +0m03.90s | +1.04% 4m38.90s | Experiments/NewPipeline/Toplevel1.vo | 4m37.97s || +0m00.92s | +0.33% 1m36.44s | Experiments/NewPipeline/Toplevel2.vo | 1m36.23s || +0m00.21s | +0.21% 0m44.38s | Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery | 0m44.09s || +0m00.28s | +0.65% 0m39.93s | p521_32.c | 0m40.58s || -0m00.64s | -1.60% 0m32.86s | p521_64.c | 0m33.84s || -0m00.98s | -2.89% 0m29.52s | Experiments/NewPipeline/ExtractionHaskell/unsaturated_solinas | 0m29.66s || -0m00.14s | -0.47% 0m22.76s | Experiments/NewPipeline/ExtractionHaskell/saturated_solinas | 0m22.88s || -0m00.11s | -0.52% 0m16.76s | Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery | 0m16.66s || +0m00.10s | +0.60% 0m14.01s | secp256k1_32.c | 0m14.03s || -0m00.01s | -0.14% 0m13.88s | p256_32.c | 0m13.79s || +0m00.09s | +0.65% 0m10.63s | p384_64.c | 0m10.67s || -0m00.03s | -0.37% 0m10.16s | Experiments/NewPipeline/ExtractionOCaml/unsaturated_solinas | 0m10.07s || +0m00.08s | +0.89% 0m09.76s | Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.ml | 0m09.92s || -0m00.16s | -1.61% 0m07.83s | Experiments/NewPipeline/ExtractionOCaml/saturated_solinas | 0m07.65s || +0m00.17s | +2.35% 0m06.60s | p224_32.c | 0m06.35s || +0m00.25s | +3.93% 0m06.54s | Experiments/NewPipeline/ExtractionOCaml/unsaturated_solinas.ml | 0m06.48s || +0m00.05s | +0.92% 0m06.42s | Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.hs | 0m06.40s || +0m00.01s | +0.31% 0m04.99s | Experiments/NewPipeline/ExtractionOCaml/saturated_solinas.ml | 0m04.94s || +0m00.04s | +1.01% 0m04.92s | Experiments/NewPipeline/ExtractionHaskell/unsaturated_solinas.hs | 0m04.96s || -0m00.04s | -0.80% 0m04.12s | Experiments/NewPipeline/ExtractionHaskell/saturated_solinas.hs | 0m04.06s || +0m00.06s | +1.47% 0m02.40s | curve25519_32.c | 0m02.40s || +0m00.00s | +0.00% 0m01.90s | p224_64.c | 0m02.02s || -0m00.12s | -5.94% 0m01.84s | p256_64.c | 0m01.83s || +0m00.01s | +0.54% 0m01.84s | secp256k1_64.c | 0m01.84s || +0m00.00s | +0.00% 0m01.48s | Experiments/NewPipeline/CLI.vo | 0m01.48s || +0m00.00s | +0.00% 0m01.48s | curve25519_64.c | 0m01.63s || -0m00.14s | -9.20% 0m01.28s | Experiments/NewPipeline/StandaloneHaskellMain.vo | 0m01.24s || +0m00.04s | +3.22% 0m01.28s | Experiments/NewPipeline/StandaloneOCamlMain.vo | 0m01.32s || -0m00.04s | -3.03%
Diffstat (limited to 'src')
-rw-r--r--src/Experiments/NewPipeline/Toplevel1.v229
1 files changed, 145 insertions, 84 deletions
diff --git a/src/Experiments/NewPipeline/Toplevel1.v b/src/Experiments/NewPipeline/Toplevel1.v
index cd55a4472..957264d3f 100644
--- a/src/Experiments/NewPipeline/Toplevel1.v
+++ b/src/Experiments/NewPipeline/Toplevel1.v
@@ -545,6 +545,8 @@ Module Pipeline.
| Value_not_leZ (descr : string) (lhs rhs : Z)
| Value_not_leQ (descr : string) (lhs rhs : Q)
| Value_not_ltZ (descr : string) (lhs rhs : Z)
+ | Value_not_lt_listZ (descr : string) (lhs rhs : list Z)
+ | Value_not_le_listZ (descr : string) (lhs rhs : list Z)
| Values_not_provably_distinctZ (descr : string) (lhs rhs : Z)
| Values_not_provably_equalZ (descr : string) (lhs rhs : Z)
| Values_not_provably_equal_listZ (descr : string) (lhs rhs : list Z)
@@ -650,6 +652,10 @@ Module Pipeline.
=> ["Value not ≤ (" ++ descr ++ ") : expected " ++ show false lhs ++ " ≤ " ++ show false rhs]
| Value_not_ltZ descr lhs rhs
=> ["Value not < (" ++ descr ++ ") : expected " ++ show false lhs ++ " < " ++ show false rhs]
+ | Value_not_lt_listZ descr lhs rhs
+ => ["Value not < (" ++ descr ++ ") : expected " ++ show false lhs ++ " < " ++ show false rhs]
+ | Value_not_le_listZ descr lhs rhs
+ => ["Value not ≤ (" ++ descr ++ ") : expected " ++ show false lhs ++ " ≤ " ++ show false rhs]
| Values_not_provably_distinctZ descr lhs rhs
=> ["Values not provably distinct (" ++ descr ++ ") : expected " ++ show true lhs ++ " ≠ " ++ show true rhs]
| Values_not_provably_equalZ descr lhs rhs
@@ -1300,9 +1306,44 @@ Hint Extern 1 (_ = cmovznz _ _ _ _) => simple apply (proj1 cmovznz_gen_correct)
Hint Immediate (proj2 cmovznz_gen_correct) : wf_gen_cache.
-Axiom admit_pf : False.
-Notation admit := (match admit_pf with end).
-
+(** XXX TODO MOVE ME *)
+Module Import HelperLemmas.
+ Lemma eval_is_bounded_by wt n' bounds bounds' f
+ (H : ZRange.type.base.option.is_bounded_by (t:=base.type.list base.type.Z) bounds f = true)
+ (Hb : bounds = Some (List.map (@Some _) bounds'))
+ (Hblen : length bounds' = n')
+ (Hwt : forall i, List.In i (seq 0 n') -> 0 <= wt i)
+ : eval wt n' (List.map lower bounds') <= eval wt n' f <= eval wt n' (List.map upper bounds').
+ Proof.
+ clear -H Hb Hblen Hwt.
+ setoid_rewrite in_seq in Hwt.
+ subst bounds.
+ pose proof H as H'; apply fold_andb_map_length in H'.
+ revert dependent bounds'; intro bounds'.
+ revert dependent f; intro f.
+ rewrite <- (List.rev_involutive bounds'), <- (List.rev_involutive f);
+ generalize (List.rev bounds') (List.rev f); clear bounds' f; intros bounds f; revert bounds f.
+ induction n' as [|n IHn], bounds as [|b bounds], f as [|f fs]; intros;
+ cbn [length rev map] in *; distr_length.
+ { rewrite !map_app in *; cbn [map] in *.
+ erewrite !eval_snoc by (distr_length; eauto).
+ cbn [ZRange.type.base.option.is_bounded_by ZRange.type.base.is_bounded_by] in *.
+ cbv [is_bounded_by_bool] in *.
+ specialize_by (intros; auto with omega).
+ specialize (Hwt n); specialize_by omega.
+ repeat first [ progress Bool.split_andb
+ | rewrite Nat.add_1_r in *
+ | rewrite fold_andb_map_snoc in *
+ | rewrite Nat.succ_inj_wd in *
+ | progress Z.ltb_to_lt
+ | progress cbn [In seq] in *
+ | match goal with
+ | [ H : length _ = ?v |- _ ] => rewrite H in *
+ | [ H : ?v = length _ |- _ ] => rewrite <- H in *
+ end ].
+ split; apply Z.add_le_mono; try apply IHn; auto; distr_length; nia. }
+ Qed.
+End HelperLemmas.
(** XXX TODO: Translate Jade's python script *)
Module Import UnsaturatedSolinas.
@@ -1371,7 +1412,10 @@ Module Import UnsaturatedSolinas.
(negb (list_beq _ Z.eqb v1 v2), Pipeline.Values_not_provably_equal_listZ "map mask m_enc ≠ m_enc (needed for to_bytes)" v1 v2));
(let v1 := eval (weight (Qnum limbwidth) (QDen limbwidth)) n m_enc in
let v2 := s - Associational.eval c in
- (negb (v1 =? v2)%Z, Pipeline.Values_not_provably_equalZ "eval m_enc ≠ s - Associational.eval c (needed for to_bytes)" v1 v2))].
+ (negb (v1 =? v2)%Z, Pipeline.Values_not_provably_equalZ "eval m_enc ≠ s - Associational.eval c (needed for to_bytes)" v1 v2));
+ (let v1 := eval (weight (Qnum limbwidth) (QDen limbwidth)) n tight_upperbounds in
+ let v2 := 2 * eval (weight (Qnum limbwidth) (QDen limbwidth)) n m_enc in
+ (negb (v1 <? v2)%Z, Pipeline.Value_not_ltZ "2 * eval m_enc ≤ eval tight_upperbounds (needed for to_bytes)" v1 v2))].
Notation type_of_strip_3arrow := ((fun (d : Prop) (_ : forall A B C, d) => d) _).
@@ -1731,7 +1775,8 @@ Module Import UnsaturatedSolinas.
| solve [ auto ] ].
Lemma use_curve_good
- : Z.pos m = s - Associational.eval c
+ : let eval := eval (weight (Qnum limbwidth) (QDen limbwidth)) n in
+ Z.pos m = s - Associational.eval c
/\ Z.pos m <> 0
/\ s - Associational.eval c <> 0
/\ s <> 0
@@ -1742,9 +1787,10 @@ Module Import UnsaturatedSolinas.
/\ 0 < Qden limbwidth <= Qnum limbwidth
/\ s = weight (Qnum limbwidth) (QDen limbwidth) n
/\ map (Z.land (Z.ones machine_wordsize)) m_enc = m_enc
- /\ eval (weight (Qnum limbwidth) (QDen limbwidth)) n m_enc = s - Associational.eval c
+ /\ eval m_enc = s - Associational.eval c
/\ Datatypes.length m_enc = n
- /\ 0 < Associational.eval c < s.
+ /\ 0 < Associational.eval c < s
+ /\ eval tight_upperbounds < 2 * eval m_enc.
Proof.
clear -curve_good.
cbv [check_args fold_right] in curve_good.
@@ -1779,9 +1825,10 @@ Module Import UnsaturatedSolinas.
{ use_curve_good_t. }
{ use_curve_good_t. }
{ use_curve_good_t. }
+ { use_curve_good_t. }
Qed.
- (** TODO: Find a better place to put the spec for [to_bytes] *)
+ (** TODO: Find a better place to put the spec for [to_bytes] and [from_bytes] *)
Definition GoodT : Prop
:= @Ring.GoodT
(Qnum limbwidth)
@@ -1803,48 +1850,19 @@ Module Import UnsaturatedSolinas.
((ZRange.type.base.option.is_bounded_by prime_bytes_bounds (type.app_curried (Interp rto_bytesv) f) = true
/\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rto_bytesv) f
= type.app_curried (t:=to_bytesT) (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f))
- /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) = (Positional.eval (weight (Qnum limbwidth) (Z.pos (Qden limbwidth))) n (fst f) mod m))).
-
- (** XXX TODO MOVE ME? *)
- Lemma eval_is_bounded_by wt n' bounds bounds' f
- (H : ZRange.type.base.option.is_bounded_by (t:=base.type.list base.type.Z) bounds f = true)
- (Hb : bounds = Some (List.map (@Some _) bounds'))
- (Hblen : length bounds' = n')
- (Hwt : forall i, List.In i (seq 0 n') -> 0 <= wt i)
- : eval wt n' (List.map lower bounds') <= eval wt n' f <= eval wt n' (List.map upper bounds').
- Proof.
- clear -H Hb Hblen Hwt.
- setoid_rewrite in_seq in Hwt.
- subst bounds.
- pose proof H as H'; apply fold_andb_map_length in H'.
- revert dependent bounds'; intro bounds'.
- revert dependent f; intro f.
- rewrite <- (List.rev_involutive bounds'), <- (List.rev_involutive f);
- generalize (List.rev bounds') (List.rev f); clear bounds' f; intros bounds f; revert bounds f.
- induction n' as [|n IHn], bounds as [|b bounds], f as [|f fs]; intros;
- cbn [length rev map] in *; distr_length.
- { rewrite !map_app in *; cbn [map] in *.
- erewrite !eval_snoc by (distr_length; eauto).
- cbn [ZRange.type.base.option.is_bounded_by ZRange.type.base.is_bounded_by] in *.
- cbv [is_bounded_by_bool] in *.
- specialize_by (intros; auto with omega).
- specialize (Hwt n); specialize_by omega.
- repeat first [ progress Bool.split_andb
- | rewrite Nat.add_1_r in *
- | rewrite fold_andb_map_snoc in *
- | rewrite Nat.succ_inj_wd in *
- | progress Z.ltb_to_lt
- | progress cbn [In seq] in *
- | match goal with
- | [ H : length _ = ?v |- _ ] => rewrite H in *
- | [ H : ?v = length _ |- _ ] => rewrite <- H in *
- end ].
- split; apply Z.add_le_mono; try apply IHn; auto; distr_length; nia. }
- Qed.
+ /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) = (Positional.eval (weight (Qnum limbwidth) (Z.pos (Qden limbwidth))) n (fst f) mod m)))
+ /\ (let from_bytesT := (base.type.list base.type.Z -> base.type.list base.type.Z)%etype in
+ forall f
+ (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=from_bytesT) (@ZRange.type.option.is_bounded_by) (prime_bytes_bounds, tt) f = true),
+ ((ZRange.type.base.option.is_bounded_by (t:=base.type.list (base.type.type_base base.type.Z)) (Some tight_bounds) (type.app_curried (Interp rfrom_bytesv) f) = true
+ /\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rfrom_bytesv) f
+ = type.app_curried (t:=from_bytesT) (from_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n) f))
+ /\ (Positional.eval (weight (Qnum limbwidth) (Z.pos (Qden limbwidth))) n (type.app_curried (t:=from_bytesT) (from_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n) f)) = (Positional.eval (weight 8 1) n_bytes (fst f)))).
+
Theorem Good : GoodT.
Proof.
- pose proof use_curve_good; destruct_head'_and; destruct_head_hnf' ex.
- split.
+ pose proof use_curve_good; cbv zeta in *; destruct_head'_and; destruct_head_hnf' ex.
+ split; [ | split ].
{ eapply Ring.Good;
lazymatch goal with
| [ H : ?P ?rop |- context[expr.Interp _ ?rop] ]
@@ -1873,29 +1891,32 @@ Module Import UnsaturatedSolinas.
{ lazymatch goal with
| [ H : eval _ _ _ = ?x |- _ <= _ < 2 * ?x ] => rewrite <- H
end.
- cbv [m_enc tight_bounds tight_upperbounds prime_upperbound_list] in H15 |- *.
- eapply eval_is_bounded_by with (wt:=weight (Qnum limbwidth) (QDen limbwidth)) in H15.
- 2:rewrite <- (map_map _ (@Some _)); reflexivity.
- 2:distr_length; reflexivity.
- rewrite ?map_map in *.
+ let H := match goal with H : ZRange.type.base.option.is_bounded_by _ _ = true |- _ => H end in
+ cbv [m_enc tight_bounds tight_upperbounds prime_upperbound_list] in H |- *;
+ eapply eval_is_bounded_by with (wt:=weight (Qnum limbwidth) (QDen limbwidth)) in H;
+ [
+ | rewrite <- (map_map _ (@Some _)); reflexivity
+ | autorewrite with distr_length; reflexivity
+ | intros; apply Z.lt_le_incl, weight_positive, wprops; lia ].
+ progress rewrite ?map_map in *.
cbn [lower upper] in *.
split.
- { etransitivity; [ erewrite <- eval_zeros | apply H15 ].
+ { destruct_head'_and.
+ etransitivity; [ erewrite <- eval_zeros | eassumption ].
apply Z.eq_le_incl; f_equal.
- repeat match goal with H : _ |- _ => revert H end; exact admit. }
- { eapply Z.le_lt_trans; [ apply H15 | ].
- assert (Hlen : length (encode (weight (Qnum limbwidth) (QDen limbwidth)) n s c (s - 1)) = n) by distr_length.
- revert Hlen.
- generalize ((encode (weight (Qnum limbwidth) (QDen limbwidth)) n s c (s - 1))).
- intro ls.
- clear.
- revert ls.
- clearbody limbwidth.
- induction n as [|n' IHn'], ls as [|l ls]; cbn [length]; intros; try omega.
- repeat match goal with H : _ |- _ => revert H end; exact admit.
- cbn [map].
- repeat match goal with H : _ |- _ => revert H end; exact admit. }
- repeat match goal with H : _ |- _ => revert H end; exact admit. } } }
+ erewrite zeros_ext_map; [ reflexivity | now autorewrite with distr_length ]. }
+ { destruct_head'_and.
+ eapply Z.le_lt_trans; [ eassumption | ].
+ assumption. } } } }
+ { cbv zeta; intros f Hf; split.
+ { apply Hfrom_bytesv; solve [ assumption | repeat split ]. }
+ { cbn [type.for_each_lhs_of_arrow type_base type.andb_bool_for_each_lhs_of_arrow ZRange.type.option.is_bounded_by fst snd] in *.
+ rewrite Bool.andb_true_iff in *; split_and'.
+ etransitivity; [ apply eval_from_bytesmod | reflexivity ];
+ auto; try omega.
+ { cbv [ZRange.type.base.option.is_bounded_by prime_bytes_bounds prime_bytes_upperbound_list n_bytes] in *.
+ erewrite Ring.length_is_bounded_by by eassumption.
+ autorewrite with distr_length; reflexivity. } } }
Qed.
End make_ring.
@@ -2525,8 +2546,10 @@ Module WordByWordMontgomery.
:= Some (List.map (fun v => Some r[0 ~> v]%zrange) prime_upperbound_list).
Definition prime_bytes_bounds : ZRange.type.option.interp (base.type.list (base.type.Z))
:= Some (List.map (fun v => Some r[0 ~> v]%zrange) prime_bytes_upperbound_list).
+ Definition saturated_upper_bounds : list Z
+ := List.repeat (2^machine_wordsize-1)%Z n.
Definition saturated_bounds : ZRange.type.option.interp (base.type.list (base.type.Z))
- := Some (List.repeat (Some r[0 ~> 2^machine_wordsize-1]%zrange) n).
+ := Some (List.map (fun u => Some r[0 ~> u]%zrange) saturated_upper_bounds).
Definition m_enc : list Z
:= encode (UniformWeight.uweight machine_wordsize) n s c (s-Associational.eval c).
@@ -2862,7 +2885,6 @@ Module WordByWordMontgomery.
/\ 0 < machine_wordsize
/\ n <> 0%nat
/\ List.length bounds = n
- /\ List.length bounds = n
/\ 0 < 1 <= machine_wordsize
/\ 0 < Associational.eval c < s
/\ (r * r') mod m = 1
@@ -2873,7 +2895,7 @@ Module WordByWordMontgomery.
Proof.
clear -curve_good.
cbv [check_args fold_right] in curve_good.
- cbv [bounds prime_bound m_enc prime_bounds] in *.
+ cbv [bounds prime_bound m_enc prime_bounds saturated_upper_bounds saturated_bounds] in *.
break_innermost_match_hyps; try discriminate.
rewrite negb_false_iff in *.
Z.ltb_to_lt.
@@ -2903,10 +2925,9 @@ Module WordByWordMontgomery.
{ use_curve_good_t. }
{ use_curve_good_t. }
{ use_curve_good_t. }
- { use_curve_good_t. }
Qed.
- (** TODO: Find a better place to put the spec for [to_bytes] *)
+ (** TODO: Find a better place to put the spec for [to_bytes] and [from_bytes] *)
Definition GoodT : Prop
:= @MontgomeryStyleRing.GoodT
machine_wordsize 1
@@ -2927,16 +2948,55 @@ Module WordByWordMontgomery.
((ZRange.type.base.option.is_bounded_by prime_bytes_bounds (type.app_curried (Interp rto_bytesv) f) = true
/\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rto_bytesv) f
= type.app_curried (t:=to_bytesT) (to_bytesmod machine_wordsize n) f))
- /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (to_bytesmod machine_wordsize n) f)) = (Positional.eval (weight machine_wordsize 1) n (fst f) mod m)))
+ (*/\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (to_bytesmod machine_wordsize n) f)) = (Positional.eval (weight machine_wordsize 1) n (fst f) mod m)*) (* duplicate from Arithmetic, except without validity *)))
+ /\ (let from_bytesT := (base.type.list base.type.Z -> base.type.list base.type.Z)%etype in
+ forall f
+ (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=from_bytesT) (@ZRange.type.option.is_bounded_by) (prime_bytes_bounds, tt) f = true),
+ ((ZRange.type.base.option.is_bounded_by (t:=base.type.list (base.type.type_base base.type.Z)) prime_bounds (type.app_curried (Interp rfrom_bytesv) f) = true
+ /\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rfrom_bytesv) f
+ = type.app_curried (t:=from_bytesT) (from_bytesmod machine_wordsize 1 n) f))
+ /\ (Positional.eval (weight machine_wordsize 1) n (type.app_curried (t:=from_bytesT) (from_bytesmod machine_wordsize 1 n) f)) = (Positional.eval (weight 8 1) n_bytes (fst f))))
/\ (forall f
- (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=(base.type.list base.type.Z -> base.type.Z)%etype) (@ZRange.type.option.is_bounded_by) (Some bounds, tt) f = true), (Interp rnonzerov (fst f) = 0) <-> ((@eval machine_wordsize n (from_montgomery_mod machine_wordsize n m m' (fst f))) mod m = 0)).
+ (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=(base.type.list base.type.Z -> base.type.Z)%etype) (@ZRange.type.option.is_bounded_by) (Some bounds, tt) f = true) (Hfvalid : valid machine_wordsize n m (fst f)), (Interp rnonzerov (fst f) = 0) <-> ((@eval machine_wordsize n (from_montgomery_mod machine_wordsize n m m' (fst f))) mod m = 0)).
+
+ (** XXX TODO: MOVE ME *)
+ Lemma is_bounded_by_repeat_In_iff {rg n'} {ls : list Z}
+ (H : @ZRange.type.base.option.is_bounded_by (base.type.list (base.type.type_base base.type.Z)) (Some (List.repeat (Some rg) n')) ls = true)
+ : forall x, List.In x ls -> lower rg <= x <= upper rg.
+ Proof using Type.
+ clear -H.
+ cbn [ZRange.type.base.option.is_bounded_by] in *.
+ rewrite fold_andb_map_iff in H.
+ destruct H as [H' H].
+ intros x H''; specialize (H (Some rg, x)).
+ repeat first [ progress subst
+ | progress cbn [fst snd] in *
+ | progress cbv [ZRange.type.base.is_bounded_by is_bounded_by_bool] in *
+ | progress autorewrite with distr_length in *
+ | progress rewrite combine_same in *
+ | progress rewrite in_map_iff in *
+ | progress specialize_by_assumption
+ | progress Bool.split_andb
+ | progress Z.ltb_to_lt
+ | solve [ auto ]
+ | match goal with
+ | [ H : context[List.In _ (combine (repeat _ _) _)] |- _ ]
+ => rewrite <- map_const, combine_map_l, in_map_iff in H
+ | [ H : (exists x, _ = _ /\ _) -> _ |- _ ]
+ => specialize (fun x0 pf => H (ex_intro _ (x0, _) (conj eq_refl pf)))
+ | [ H : (exists x, _ = _ /\ _) -> _ |- _ ]
+ => specialize (fun pf => H (ex_intro _ _ (conj eq_refl pf)))
+ | [ H : forall x, List.In (x, ?y) _ -> _ |- _ ]
+ => specialize (H y)
+ end ].
+ Qed.
(** XXX TODO MOVE ME *)
Local Opaque valid addmod submod oppmod encodemod mulmod from_montgomery_mod nonzeromod.
Theorem Good : GoodT.
Proof.
pose proof use_curve_good; destruct_head'_and; destruct_head_hnf' ex.
- split; [ | split ].
+ split; [ | repeat apply conj ].
{ eapply MontgomeryStyleRing.Good;
lazymatch goal with
| [ H : ?P ?rop |- context[expr.Interp _ ?rop] ]
@@ -2957,21 +3017,22 @@ Module WordByWordMontgomery.
| eapply nonzeromod_correct
| intros; apply conj
| omega ]. }
+ { cbv zeta; intros f Hf.
+ apply Hto_bytesv; solve [ assumption | repeat split ]. }
{ cbv zeta; intros f Hf; split.
- { apply Hto_bytesv; solve [ assumption | repeat split ]. }
+ { apply Hfrom_bytesv; solve [ assumption | repeat split ]. }
{ cbn [type.for_each_lhs_of_arrow type_base type.andb_bool_for_each_lhs_of_arrow ZRange.type.option.is_bounded_by fst snd] in *.
rewrite Bool.andb_true_iff in *; split_and'.
- apply to_bytesmod_correct; eauto; [].
- split; cbv [small].
- repeat match goal with H : _ |- _ => revert H end; exact admit.
- repeat match goal with H : _ |- _ => revert H end; exact admit. } }
+ etransitivity; [ apply eval_from_bytesmod | reflexivity ];
+ auto; try omega.
+ { cbv [ZRange.type.base.option.is_bounded_by prime_bytes_bounds prime_bytes_upperbound_list n_bytes] in *.
+ erewrite Ring.length_is_bounded_by by eassumption.
+ autorewrite with distr_length; reflexivity. } } }
{ intros.
split; [ intro H'; eapply nonzeromod_correct;
[ .. | rewrite <- H'; symmetry; eapply Hrnonzerov ]
| etransitivity; [ apply Hrnonzerov | eapply nonzeromod_correct; [ .. | eassumption ] ] ];
- try solve [ eassumption | repeat split ].
- repeat match goal with H : _ |- _ => revert H end; exact admit.
- repeat match goal with H : _ |- _ => revert H end; exact admit. }
+ try solve [ eassumption | repeat split ]. }
Qed.
End make_ring.