aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Robert Sloan <varomodt@google.com>2016-10-24 11:41:47 -0700
committerGravatar Robert Sloan <varomodt@google.com>2016-10-24 11:41:47 -0700
commit6c29b39c2c0eafdd6f92e7b3d67c451b3c769af5 (patch)
tree532ed133b3e9a2517aaedb95b7b0a910e25b9049
parentb31a3355d3e134e346d77d2a3715a334d7633c01 (diff)
parentea3bf2b136dd9f439f6c568f899c15aff2b8b6cb (diff)
Merge branch 'rsloan-phoas' of github.com:mit-plv/fiat-crypto into rsloan-phoas
-rw-r--r--_CoqProject89
-rw-r--r--src/Assembly/Compile.v7
-rw-r--r--src/Assembly/Conversions.v6
-rw-r--r--src/Assembly/Evaluables.v12
-rw-r--r--src/Assembly/GF25519BoundedInstantiation.v34
-rw-r--r--src/Assembly/HL.v3
-rw-r--r--src/Assembly/LL.v9
-rw-r--r--src/CompleteEdwardsCurve/ExtendedCoordinates.v13
-rw-r--r--src/Experiments/Ed25519.v347
-rw-r--r--src/Experiments/ExtrHaskellNats.v94
-rw-r--r--src/ModularArithmetic/ModularBaseSystem.v14
-rw-r--r--src/ModularArithmetic/ModularBaseSystemList.v36
-rw-r--r--src/ModularArithmetic/ModularBaseSystemListProofs.v148
-rw-r--r--src/ModularArithmetic/ModularBaseSystemOpt.v43
-rw-r--r--src/ModularArithmetic/ModularBaseSystemProofs.v28
-rw-r--r--src/Specific/GF25519.v59
-rw-r--r--src/Specific/GF25519Bounded.v212
-rw-r--r--src/Specific/GF25519BoundedCommon.v81
-rw-r--r--src/Util/Bool.v10
-rw-r--r--src/Util/LetIn.v4
-rw-r--r--src/Util/WordUtil.v19
21 files changed, 899 insertions, 369 deletions
diff --git a/_CoqProject b/_CoqProject
index 757d85fe7..17a326a12 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -3,27 +3,35 @@
Bedrock/Nomega.v
Bedrock/Word.v
src/Algebra.v
+src/BaseSystem.v
+src/BaseSystemProofs.v
+src/EdDSARepChange.v
+src/Testbit.v
src/Assembly/Bounds.v
src/Assembly/Compile.v
src/Assembly/Conversions.v
src/Assembly/Evaluables.v
-src/Assembly/GF25519BoundedInstantiation.v
src/Assembly/GF25519.v
+src/Assembly/GF25519BoundedInstantiation.v
src/Assembly/HL.v
src/Assembly/LL.v
src/Assembly/PhoasCommon.v
src/Assembly/Pipeline.v
+src/Assembly/Qhasm.v
src/Assembly/QhasmCommon.v
src/Assembly/QhasmEvalCommon.v
src/Assembly/QhasmUtil.v
-src/Assembly/Qhasm.v
src/Assembly/State.v
src/Assembly/StringConversion.v
src/Assembly/WordizeUtil.v
-src/BaseSystemProofs.v
-src/BaseSystem.v
-src/BoundedArithmetic/ArchitectureToZLikeProofs.v
src/BoundedArithmetic/ArchitectureToZLike.v
+src/BoundedArithmetic/ArchitectureToZLikeProofs.v
+src/BoundedArithmetic/Eta.v
+src/BoundedArithmetic/Interface.v
+src/BoundedArithmetic/InterfaceProofs.v
+src/BoundedArithmetic/StripCF.v
+src/BoundedArithmetic/X86ToZLike.v
+src/BoundedArithmetic/X86ToZLikeProofs.v
src/BoundedArithmetic/Double/Core.v
src/BoundedArithmetic/Double/Proofs/BitwiseOr.v
src/BoundedArithmetic/Double/Proofs/Decode.v
@@ -31,10 +39,10 @@ src/BoundedArithmetic/Double/Proofs/LoadImmediate.v
src/BoundedArithmetic/Double/Proofs/Multiply.v
src/BoundedArithmetic/Double/Proofs/RippleCarryAddSub.v
src/BoundedArithmetic/Double/Proofs/SelectConditional.v
-src/BoundedArithmetic/Double/Proofs/ShiftLeftRightTactic.v
src/BoundedArithmetic/Double/Proofs/ShiftLeft.v
-src/BoundedArithmetic/Double/Proofs/ShiftRightDoubleWordImmediate.v
+src/BoundedArithmetic/Double/Proofs/ShiftLeftRightTactic.v
src/BoundedArithmetic/Double/Proofs/ShiftRight.v
+src/BoundedArithmetic/Double/Proofs/ShiftRightDoubleWordImmediate.v
src/BoundedArithmetic/Double/Proofs/SpreadLeftImmediate.v
src/BoundedArithmetic/Double/Repeated/Core.v
src/BoundedArithmetic/Double/Repeated/Proofs/BitwiseOr.v
@@ -45,42 +53,29 @@ src/BoundedArithmetic/Double/Repeated/Proofs/RippleCarryAddSub.v
src/BoundedArithmetic/Double/Repeated/Proofs/SelectConditional.v
src/BoundedArithmetic/Double/Repeated/Proofs/ShiftLeftRight.v
src/BoundedArithmetic/Double/Repeated/Proofs/ShiftRightDoubleWordImmediate.v
-src/BoundedArithmetic/Eta.v
-src/BoundedArithmetic/InterfaceProofs.v
-src/BoundedArithmetic/Interface.v
-src/BoundedArithmetic/StripCF.v
-src/BoundedArithmetic/X86ToZLikeProofs.v
-src/BoundedArithmetic/X86ToZLike.v
src/CompleteEdwardsCurve/CompleteEdwardsCurveTheorems.v
src/CompleteEdwardsCurve/ExtendedCoordinates.v
src/CompleteEdwardsCurve/Pre.v
-src/EdDSARepChange.v
src/Encoding/EncodingTheorems.v
src/Encoding/ModularWordEncodingPre.v
src/Encoding/ModularWordEncodingTheorems.v
-src/Encoding/PointEncodingPre.v
src/Encoding/PointEncoding.v
+src/Encoding/PointEncodingPre.v
src/Experiments/Ed25519.v
+src/Experiments/ExtrHaskellNats.v
src/Experiments/GenericFieldPow.v
src/Experiments/MontgomeryCurve.v
-src/ModularArithmetic/BarrettReduction/ZBounded.v
-src/ModularArithmetic/BarrettReduction/ZGeneralized.v
-src/ModularArithmetic/BarrettReduction/ZHandbook.v
-src/ModularArithmetic/BarrettReduction/Z.v
src/ModularArithmetic/Conversion.v
-src/ModularArithmetic/ExtendedBaseVector.v
src/ModularArithmetic/ExtPow2BaseMulProofs.v
+src/ModularArithmetic/ExtendedBaseVector.v
src/ModularArithmetic/ModularArithmeticTheorems.v
-src/ModularArithmetic/ModularBaseSystemListProofs.v
+src/ModularArithmetic/ModularBaseSystem.v
src/ModularArithmetic/ModularBaseSystemList.v
+src/ModularArithmetic/ModularBaseSystemListProofs.v
src/ModularArithmetic/ModularBaseSystemOpt.v
src/ModularArithmetic/ModularBaseSystemProofs.v
-src/ModularArithmetic/ModularBaseSystem.v
-src/ModularArithmetic/Montgomery/ZBounded.v
-src/ModularArithmetic/Montgomery/ZProofs.v
-src/ModularArithmetic/Montgomery/Z.v
-src/ModularArithmetic/Pow2BaseProofs.v
src/ModularArithmetic/Pow2Base.v
+src/ModularArithmetic/Pow2BaseProofs.v
src/ModularArithmetic/Pre.v
src/ModularArithmetic/PrimeFieldTheorems.v
src/ModularArithmetic/PseudoMersenneBaseParamProofs.v
@@ -88,19 +83,32 @@ src/ModularArithmetic/PseudoMersenneBaseParams.v
src/ModularArithmetic/Tutorial.v
src/ModularArithmetic/ZBounded.v
src/ModularArithmetic/ZBoundedZ.v
+src/ModularArithmetic/BarrettReduction/Z.v
+src/ModularArithmetic/BarrettReduction/ZBounded.v
+src/ModularArithmetic/BarrettReduction/ZGeneralized.v
+src/ModularArithmetic/BarrettReduction/ZHandbook.v
+src/ModularArithmetic/Montgomery/Z.v
+src/ModularArithmetic/Montgomery/ZBounded.v
+src/ModularArithmetic/Montgomery/ZProofs.v
src/Reflection/CommonSubexpressionElimination.v
src/Reflection/Conversion.v
src/Reflection/CountLets.v
src/Reflection/FilterLive.v
-src/Reflection/InlineInterp.v
src/Reflection/Inline.v
+src/Reflection/InlineInterp.v
src/Reflection/InlineWf.v
src/Reflection/InputSyntax.v
src/Reflection/InterpProofs.v
-src/Reflection/LinearizeInterp.v
src/Reflection/Linearize.v
+src/Reflection/LinearizeInterp.v
src/Reflection/LinearizeWf.v
src/Reflection/MapInterp.v
+src/Reflection/Reify.v
+src/Reflection/Syntax.v
+src/Reflection/TestCase.v
+src/Reflection/WfProofs.v
+src/Reflection/WfReflective.v
+src/Reflection/WfRel.v
src/Reflection/Named/Compile.v
src/Reflection/Named/ContextOn.v
src/Reflection/Named/DeadCodeElimination.v
@@ -108,31 +116,24 @@ src/Reflection/Named/EstablishLiveness.v
src/Reflection/Named/NameUtil.v
src/Reflection/Named/RegisterAssign.v
src/Reflection/Named/Syntax.v
-src/Reflection/Reify.v
-src/Reflection/Syntax.v
-src/Reflection/TestCase.v
-src/Reflection/WfProofs.v
-src/Reflection/WfReflective.v
-src/Reflection/WfRel.v
src/Spec/CompleteEdwardsCurve.v
src/Spec/Ed25519.v
src/Spec/EdDSA.v
src/Spec/Encoding.v
-src/Specific/FancyMachine256/Barrett.v
-src/Specific/FancyMachine256/Core.v
-src/Specific/FancyMachine256/Montgomery.v
-src/Specific/GF1305.v
-src/Specific/GF25519BoundedCommon.v
-src/Specific/GF25519Bounded.v
-src/Specific/GF25519.v
-src/Specific/SC25519.v
src/Spec/ModularArithmetic.v
src/Spec/ModularWordEncoding.v
src/Spec/MxDH.v
src/Spec/WeierstrassCurve.v
-src/Tactics/Algebra_syntax/Nsatz.v
+src/Specific/GF1305.v
+src/Specific/GF25519.v
+src/Specific/GF25519Bounded.v
+src/Specific/GF25519BoundedCommon.v
+src/Specific/SC25519.v
+src/Specific/FancyMachine256/Barrett.v
+src/Specific/FancyMachine256/Core.v
+src/Specific/FancyMachine256/Montgomery.v
src/Tactics/VerdiTactics.v
-src/Testbit.v
+src/Tactics/Algebra_syntax/Nsatz.v
src/Test/Curve25519SpecTestVectors.v
src/Util/AdditionChainExponentiation.v
src/Util/AutoRewrite.v
diff --git a/src/Assembly/Compile.v b/src/Assembly/Compile.v
index 91eb37a16..e072342a5 100644
--- a/src/Assembly/Compile.v
+++ b/src/Assembly/Compile.v
@@ -9,6 +9,8 @@ Require Import Crypto.Assembly.QhasmEvalCommon.
Require Import Crypto.Assembly.QhasmCommon.
Require Import Crypto.Assembly.Qhasm.
+Local Arguments LetIn.Let_In _ _ _ _ / .
+
Module CompileHL.
Section Compilation.
Context {T: Type}.
@@ -281,11 +283,12 @@ Module CompileLL.
(fun rt var op x y out => Some out)
(fun t' a => Some (vars a)).
- Fixpoint fillInputs {t inputs} (prog: NAry inputs Z (WExpr t)) {struct inputs}: WExpr t :=
+ Fixpoint fillInputs t inputs (prog: NAry inputs Z (WExpr t)) {struct inputs}: WExpr t :=
match inputs as inputs' return NAry inputs' Z (WExpr t) -> NAry O Z (WExpr t) with
| O => fun p => p
- | S inputs'' => fun p => fillInputs (p (Z.of_nat inputs))
+ | S inputs'' => fun p => @fillInputs _ _ (p (Z.of_nat inputs))
end prog.
+ Global Arguments fillInputs {t inputs} _.
Definition compile {t inputs} (p: NAry inputs Z (WExpr t)): option (Program * list nat) :=
let p' := fillInputs p in
diff --git a/src/Assembly/Conversions.v b/src/Assembly/Conversions.v
index e4ea4b5d1..c24cf618f 100644
--- a/src/Assembly/Conversions.v
+++ b/src/Assembly/Conversions.v
@@ -18,6 +18,8 @@ Require Import Coq.NArith.Nnat Coq.NArith.Ndigits.
Require Import Coq.Bool.Sumbool.
+Local Arguments LetIn.Let_In _ _ _ _ / .
+
Definition typeMap {A B t} (f: A -> B) (x: @interp_type A t): @interp_type B t.
Proof.
induction t; [refine (f x)|].
@@ -282,7 +284,7 @@ Module LLConversions.
Lemma roundTrip_0 : @toT Correctness.B BE (@fromT Z ZE 0%Z) <> None.
Proof.
intros; unfold toT, fromT, BE, ZE, BoundedEvaluable, ZEvaluable, bwFromRWV;
- kill_dec; simpl; kill_dec; simpl; try abstract (intro Z; inversion Z);
+ break_match; simpl; try break_match; simpl; try abstract (intro Z; inversion Z);
pose proof (Npow2_gt0 n); simpl in *; nomega.
Qed.
@@ -361,7 +363,7 @@ Module LLConversions.
kill_dec; simpl in *; kill_dec; first [reflexivity|nomega]. *)
+ unfold bcheck, getBounds in *.
- replace (interp_binop op _ _)
+ replace (interp_binop op (interp_arg x) (interp_arg y))
with (varBoundedToZ (n := n) (opBounded op
(interp_arg' boundVarInterp (convertArg _ x))
(interp_arg' boundVarInterp (convertArg _ y)))).
diff --git a/src/Assembly/Evaluables.v b/src/Assembly/Evaluables.v
index 8d68ac696..c4aa56175 100644
--- a/src/Assembly/Evaluables.v
+++ b/src/Assembly/Evaluables.v
@@ -13,7 +13,7 @@ Section BaseTypes.
Record RangeWithValue := rwv {
rwv_low: N;
rwv_value: N;
- rwv_high: N;
+ rwv_high: N
}.
Record BoundedWord {n} := bounded {
@@ -23,7 +23,7 @@ Section BaseTypes.
ge_low: (bw_low <= wordToN bw_value)%N;
le_high: (wordToN bw_value <= bw_high)%N;
- high_bound: (bw_high < Npow2 n)%N;
+ high_bound: (bw_high < Npow2 n)%N
}.
End BaseTypes.
@@ -652,11 +652,11 @@ Section BoundedWord.
eand := fun x y => omap x (fun X => omap y (fun Y => bapp range_and_valid X Y));
eltb := fun x y =>
- orElse false (omap x (fun X => omap y (fun Y =>
+ orElse false (omap x (fun X => omap y (fun Y =>
Some (N.ltb (wordToN (bw_value X)) (wordToN (bw_value Y))))));
eeqb := fun x y =>
- orElse false (omap x (fun X => omap y (fun Y =>
+ orElse false (omap x (fun X => omap y (fun Y =>
Some (N.eqb (wordToN (bw_value X)) (wordToN (bw_value Y))))))
}.
End BoundedWord.
@@ -729,7 +729,7 @@ Section RangeWithValue.
| (Some (rwv xlow xv xhigh), Some (rwv ylow yv yhigh)) =>
N.ltb xv yv
- | _ => false
+ | _ => false
end;
eeqb := fun x y =>
@@ -738,6 +738,6 @@ Section RangeWithValue.
andb (andb (N.eqb xlow ylow) (N.eqb xhigh yhigh)) (N.eqb xv yv)
| _ => false
- end;
+ end
}.
End RangeWithValue.
diff --git a/src/Assembly/GF25519BoundedInstantiation.v b/src/Assembly/GF25519BoundedInstantiation.v
index 83b0dd4bf..07c074f5e 100644
--- a/src/Assembly/GF25519BoundedInstantiation.v
+++ b/src/Assembly/GF25519BoundedInstantiation.v
@@ -7,6 +7,7 @@ Require Import Crypto.Assembly.GF25519.
Require Import Crypto.Specific.GF25519.
Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.Tuple.
(* Totally fine to edit these definitions; DO NOT change the type signatures at all *)
@@ -43,6 +44,39 @@ Definition interp_uexpr : ExprUnOp -> Specific.GF25519BoundedCommon.fe25519W ->
:= interp_uexpr'.
Axiom rfreeze : ExprUnOp.
+Declare Reduction asm_interp
+ := cbv [id
+ interp_bexpr interp_uexpr interp_bexpr' interp_uexpr'
+ radd rsub rmul ropp (*rfreeze*)
+ GF25519.GF25519.Add.wordProg GF25519.GF25519.AddExpr.bits GF25519.GF25519.Add.llProg GF25519.GF25519.AddExpr.hlProg GF25519.GF25519.AddExpr.inputs
+ GF25519.GF25519.Sub.wordProg GF25519.GF25519.SubExpr.bits GF25519.GF25519.Sub.llProg GF25519.GF25519.SubExpr.hlProg GF25519.GF25519.SubExpr.inputs
+ GF25519.GF25519.Mul.wordProg GF25519.GF25519.MulExpr.bits GF25519.GF25519.Mul.llProg GF25519.GF25519.MulExpr.hlProg GF25519.GF25519.MulExpr.inputs
+ GF25519.GF25519.Opp.wordProg GF25519.GF25519.OppExpr.bits GF25519.GF25519.Opp.llProg GF25519.GF25519.OppExpr.hlProg GF25519.GF25519.OppExpr.inputs
+ (*GF25519.GF25519.Freeze.wordProg GF25519.GF25519.FreezeExpr.bits GF25519.GF25519.Freeze.llProg GF25519.GF25519.FreezeExpr.hlProg GF25519.GF25519.FreezeExpr.inputs *)
+ GF25519.GF25519.bits GF25519.GF25519.FE
+ QhasmCommon.liftN QhasmCommon.NArgMap Compile.CompileHL.compile LL.LL.under_lets LL.LL.interp LL.LL.interp_arg LL.LL.match_arg_Prod Conversions.LLConversions.convertZToWord Conversions.LLConversions.convertExpr Conversions.LLConversions.convertArg Conversions.LLConversions.convertVar PhoasCommon.type_rect PhoasCommon.type_rec PhoasCommon.type_ind PhoasCommon.interp_binop LL.LL.uninterp_arg
+ Evaluables.ezero Evaluables.toT Evaluables.fromT Evaluables.eadd Evaluables.esub Evaluables.emul Evaluables.eshiftr Evaluables.eand Evaluables.eltb Evaluables.eeqb
+ Evaluables.WordEvaluable Evaluables.ZEvaluable].
+
+Definition interp_radd : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := Eval asm_interp in interp_bexpr radd.
+Print interp_radd.
+Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
+Definition interp_rsub : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := Eval asm_interp in interp_bexpr rsub.
+(*Print interp_rsub.*)
+Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
+Definition interp_rmul : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := Eval asm_interp in interp_bexpr rmul.
+(*Print interp_rmul.*)
+Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
+Definition interp_ropp : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := Eval asm_interp in interp_uexpr ropp.
+Definition interp_ropp_correct : interp_ropp = interp_uexpr ropp := eq_refl.
+Definition interp_rfreeze : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := Eval asm_interp in interp_uexpr rfreeze.
+Definition interp_rfreeze_correct : interp_rfreeze = interp_uexpr rfreeze := eq_refl.
+
Local Notation binop_correct_and_bounded rop op
:= (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
Local Notation unop_correct_and_bounded rop op
diff --git a/src/Assembly/HL.v b/src/Assembly/HL.v
index 14ca2edca..2107b7f0a 100644
--- a/src/Assembly/HL.v
+++ b/src/Assembly/HL.v
@@ -1,5 +1,6 @@
Require Import Crypto.Assembly.PhoasCommon.
Require Import Coq.setoid_ring.InitialRing.
+Require Import Crypto.Util.LetIn.
Module HL.
Section Language.
@@ -27,7 +28,7 @@ Module HL.
| Const n => n
| Var _ n => n
| Binop _ _ _ op e1 e2 => interp_binop op (interp e1) (interp e2)
- | Let _ ex _ eC => let x := interp ex in interp (eC x)
+ | Let _ ex _ eC => dlet x := interp ex in interp (eC x)
| Pair _ e1 _ e2 => (interp e1, interp e2)
| MatchPair _ _ ep _ eC => let (v1, v2) := interp ep in interp (eC v1 v2)
end.
diff --git a/src/Assembly/LL.v b/src/Assembly/LL.v
index fd0a92f96..e0588214c 100644
--- a/src/Assembly/LL.v
+++ b/src/Assembly/LL.v
@@ -1,4 +1,7 @@
Require Import Crypto.Assembly.PhoasCommon.
+Require Import Crypto.Util.LetIn.
+
+Local Arguments Let_In / _ _ _ _.
Module LL.
Section Language.
@@ -61,7 +64,7 @@ Module LL.
match x' with
| (x0, x1) => Pair (uninterp_arg_as_var x0) (uninterp_arg_as_var x1)
end
- | TT => Var
+ | TT => Var
end x.
Fixpoint interp' {V t} (f: V -> T) (e:expr t) : interp_type t :=
@@ -74,7 +77,7 @@ Module LL.
Fixpoint interp {t} (e:expr t) : interp_type t :=
match e with
| LetBinop _ _ _ op a b _ eC =>
- let x := interp_binop op (interp_arg a) (interp_arg b) in interp (eC (uninterp_arg x))
+ dlet x := interp_binop op (interp_arg a) (interp_arg b) in interp (eC (uninterp_arg x))
| Return _ a => interp_arg a
end.
@@ -153,7 +156,7 @@ Module LL.
induction t as [|i0 v0 i1 v1]; simpl; intros; try reflexivity.
break_match; subst; simpl.
unfold interp_arg in *.
- cbn; rewrite v0, v1; reflexivity.
+ simpl; rewrite v0, v1; reflexivity.
Qed.
Lemma interp_under_lets {T} {_: Evaluable T} {t: type} {tC: type}
diff --git a/src/CompleteEdwardsCurve/ExtendedCoordinates.v b/src/CompleteEdwardsCurve/ExtendedCoordinates.v
index 3e447cb04..5a6f7588a 100644
--- a/src/CompleteEdwardsCurve/ExtendedCoordinates.v
+++ b/src/CompleteEdwardsCurve/ExtendedCoordinates.v
@@ -47,6 +47,7 @@ Module Extended.
| _ => solve [eauto]
| _ => solve [intuition eauto]
| _ => solve [etransitivity; eauto]
+ | |- _ => rewrite <-!(field_div_definition(field:=field)) in *
| |- _*_ <> 0 => apply Ring.zero_product_iff_zero_factor
| [H: _ |- _ ] => solve [intro; apply H; super_nsatz]
| |- Feq _ _ => super_nsatz
@@ -62,7 +63,7 @@ Module Extended.
(let (x,y) := E.coordinates P in (x, y, 1, x*y)) _.
Program Definition to_twisted (P:point) : Epoint := exist _
- (let '(X,Y,Z,T) := coordinates P in ((X/Z), (Y/Z))) _.
+ (let '(X,Y,Z,T) := coordinates P in let iZ := Finv Z in ((X*iZ), (Y*iZ))) _.
Definition eq (P Q:point) := E.eq (to_twisted P) (to_twisted Q).
Global Instance DecidableRel_eq : Decidable.DecidableRel eq := _.
@@ -128,7 +129,12 @@ Module Extended.
pose proof (add_coordinates_correct P Q) as Hrep.
destruct P as [ [ [ [ ] ? ] ? ] [ HP [ ] ] ]; destruct Q as [ [ [ [ ] ? ] ? ] [ HQ [ ] ] ].
autounfold with bash in *; simpl in *.
- destruct Hrep as [HA HB]. rewrite <-!HA, <-!HB; clear HA HB.
+ destruct Hrep as [HA HB].
+ pose proof (field_div_definition(field:=field)) as Hdiv; symmetry in Hdiv;
+ (rewrite_strat bottomup Hdiv);
+ (rewrite_strat bottomup Hdiv in HA);
+ (rewrite_strat bottomup Hdiv in HB).
+ rewrite <-!HA, <-!HB; clear HA HB.
split; reflexivity.
Qed.
@@ -255,7 +261,8 @@ Module Extended.
| [p: point |- _ ] => destruct p as [ [ [ [ ] ? ] ? ] [ ? [ ? ? ] ] ]
| |- context[point_phi] => setoid_rewrite point_phi_correct
| |- _ => progress cbv [fst snd coordinates proj1_sig eq to_twisted E.eq E.coordinates fieldwise fieldwise' add add_coordinates ref_phi] in *
- | |- Keq ?x ?x => reflexivity
+ | |- _ => rewrite <-!(field_div_definition(field:=fieldF)) in *
+ | |- _ => rewrite <-!(field_div_definition(field:=fieldK)) in *
| |- Keq ?x ?y => rewrite_strat bottomup hints field_homomorphism
| [ H : Feq _ _ |- Keq (phi _) (phi _)] => solve [f_equiv; intuition]
end.
diff --git a/src/Experiments/Ed25519.v b/src/Experiments/Ed25519.v
index 39de39262..0961aa77d 100644
--- a/src/Experiments/Ed25519.v
+++ b/src/Experiments/Ed25519.v
@@ -61,7 +61,7 @@ Definition coord_to_extended (xy : GF25519.fe25519 * GF25519.fe25519) pf :=
(exist Pre.onCurve xy pf).
Definition extended_to_coord (P : Erep) : (GF25519.fe25519 * GF25519.fe25519) :=
- CompleteEdwardsCurve.E.coordinates (ExtendedCoordinates.Extended.to_twisted P).
+ CompleteEdwardsCurve.E.coordinates (ExtendedCoordinates.Extended.to_twisted P (field:=GF25519.field25519)).
Lemma encode_eq_iff : forall x y : ModularArithmetic.F.F GF25519.modulus,
ModularBaseSystem.eq
@@ -103,7 +103,7 @@ Definition feEnc (x : GF25519.fe25519) : Word.word 255 :=
(Word.combine (ZNWord 32 x4)
(Word.combine (ZNWord 32 x5)
(Word.combine (ZNWord 32 x6) (ZNWord 31 x7))))))).
-
+Check GF25519.ge_modulus.
Definition feDec (w : Word.word 255) : option GF25519.fe25519 :=
let w0 := Word.split1 32 _ w in
let a0 := Word.split2 32 _ w in
@@ -120,7 +120,7 @@ Definition feDec (w : Word.word 255) : option GF25519.fe25519 :=
let w6 := Word.split1 32 _ a5 in
let w7 := Word.split2 32 _ a5 in
let result := (GF25519.unpack (WordNZ w0, WordNZ w1, WordNZ w2, WordNZ w3, WordNZ w4, WordNZ w5, WordNZ w6, WordNZ w7)) in
- if GF25519.ge_modulus result
+ if Z.eqb (GF25519.ge_modulus result) 1
then None else (Some result).
Let ERepEnc :=
@@ -129,7 +129,7 @@ Let ERepEnc :=
(Kenc := feEnc)
(Kpoint := Erep)
(Kpoint_to_coord := fun P => CompleteEdwardsCurve.E.coordinates
- (ExtendedCoordinates.Extended.to_twisted P))
+ (ExtendedCoordinates.Extended.to_twisted P (field:=GF25519.field25519)))
).
Let SRep := SC25519.SRep.
@@ -175,7 +175,7 @@ Let SRepERepMul : SRep -> Erep -> Erep :=
.
Lemma SRepERepMul_correct n P :
- ExtendedCoordinates.Extended.eq
+ ExtendedCoordinates.Extended.eq (field:=GF25519.field25519)
(EToRep (CompleteEdwardsCurve.E.mul n P))
(SRepERepMul (S2Rep (ModularArithmetic.F.of_nat l n)) (EToRep P)).
Proof.
@@ -225,7 +225,7 @@ Proof.
Qed.
Lemma ext_eq_correct : forall p q : Erep,
- ExtendedCoordinates.Extended.eq p q <->
+ ExtendedCoordinates.Extended.eq (field:=GF25519.field25519) p q <->
Tuple.fieldwise (n := 2) ModularBaseSystem.eq (extended_to_coord p) (extended_to_coord q).
Proof.
cbv [extended_to_coord]; intros.
@@ -243,10 +243,10 @@ Let SRepEnc : SRep -> Word.word b := (fun x => Word.NToWord _ (Z.to_N x)).
Axiom SRepERepMul_correct:
forall (n : nat) (P : E),
- ExtendedCoordinates.Extended.eq (EToRep (CompleteEdwardsCurve.E.mul n P))
+ ExtendedCoordinates.Extended.eq (field:=GF25519.field25519) (EToRep (CompleteEdwardsCurve.E.mul n P))
(SRepERepMul (S2Rep (ModularArithmetic.F.of_nat l n)) (EToRep P)).
-Axiom Proper_SRepERepMul : Proper (SC25519.SRepEq ==> ExtendedCoordinates.Extended.eq ==> ExtendedCoordinates.Extended.eq) SRepERepMul.
+Axiom Proper_SRepERepMul : Proper (SC25519.SRepEq ==> ExtendedCoordinates.Extended.eq (field:=GF25519.field25519) ==> ExtendedCoordinates.Extended.eq (field:=GF25519.field25519)) SRepERepMul.
Axiom SRepEnc_correct : forall x : ModularArithmetic.F.F l, Senc x = SRepEnc (S2Rep x).
@@ -277,23 +277,28 @@ Let ERepB : Erep.
exists rB. exact onCurve_ERepB.
Defined.
-Let ERepB_correct : ExtendedCoordinates.Extended.eq ERepB (EToRep B). vm_decide_no_check. Qed.
-
-Axiom ERep_group :
- @Algebra.group Erep
- (@ExtendedCoordinates.Extended.eq GF25519.fe25519
- (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_ GF25519.add
- GF25519.mul (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d) ErepAdd
- (@ExtendedCoordinates.Extended.zero GF25519.fe25519
- (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_
- GF25519.opp GF25519.add GF25519.sub GF25519.mul GF25519.inv
- (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d GF25519.field25519
- twedprm_ERep _)
- (@ExtendedCoordinates.Extended.opp GF25519.fe25519
- (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_
- GF25519.opp GF25519.add GF25519.sub GF25519.mul GF25519.inv
- (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d GF25519.field25519
- twedprm_ERep _).
+Let ERepB_correct : ExtendedCoordinates.Extended.eq (field:=GF25519.field25519) ERepB (EToRep B). vm_decide_no_check. Qed.
+
+Axiom ERepGroup :
+ @Algebra.group Erep
+ (@ExtendedCoordinates.Extended.eq GF25519.fe25519
+ (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_ GF25519.opp
+ GF25519.add GF25519.sub GF25519.mul GF25519.inv
+ (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d GF25519.field25519
+ (fun x y : GF25519.fe25519 =>
+ @ModularArithmeticTheorems.F.eq_dec GF25519.modulus
+ (@ModularBaseSystem.decode GF25519.modulus GF25519.params25519 x)
+ (@ModularBaseSystem.decode GF25519.modulus GF25519.params25519 y))) ErepAdd
+ (@ExtendedCoordinates.Extended.zero GF25519.fe25519
+ (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_
+ _ GF25519.add _ GF25519.mul _
+ (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d GF25519.field25519
+ twedprm_ERep _)
+ (@ExtendedCoordinates.Extended.opp GF25519.fe25519
+ (@ModularBaseSystem.eq GF25519.modulus GF25519.params25519) GF25519.zero_ GF25519.one_
+ _ GF25519.add _ GF25519.mul _
+ (@ModularBaseSystem.div GF25519.modulus GF25519.params25519) a d GF25519.field25519
+ twedprm_ERep _).
Let sign := @EdDSARepChange.sign E
(@CompleteEdwardsCurveTheorems.E.eq Fq (@eq Fq) (@ModularArithmetic.F.one q)
@@ -342,7 +347,7 @@ Let sign_correct : forall pk sk {mlen} (msg:Word.word mlen), sign pk sk _ msg =
(* ErepAdd := *) ErepAdd
(* ErepId := *) ExtendedCoordinates.Extended.zero
(* ErepOpp := *) ExtendedCoordinates.Extended.opp
- (* Agroup := *) ERep_group
+ (* Agroup := *) ERepGroup
(* EToRep := *) EToRep
(* ERepEnc := *) ERepEnc
(* ERepEnc_correct := *) ERepEnc_correct
@@ -512,10 +517,13 @@ Extract Inlined Constant eq_rec_r => "".
Extract Inductive comparison =>
"Prelude.Ordering" ["Prelude.EQ" "Prelude.LT" "Prelude.GT"].
-(** Bool *)
+(** Bool, sumbool, Decidable *)
Extract Inductive bool => "Prelude.Bool" ["Prelude.True" "Prelude.False"].
Extract Inductive sumbool => "Prelude.Bool" ["Prelude.True" "Prelude.False"].
+Extract Inductive Bool.reflect => "Prelude.Bool" ["Prelude.True" "Prelude.False"].
+Extract Inlined Constant Bool.iff_reflect => "".
+Extraction Inline Crypto.Util.Decidable.Decidable Crypto.Util.Decidable.dec.
(* Extract Inlined Constant Equality.bool_beq => *)
(* "((Prelude.==) :: Prelude.Bool -> Prelude.Bool -> Prelude.Bool)". *)
@@ -529,6 +537,11 @@ Extract Inlined Constant orb => "(Prelude.||)".
Extract Inlined Constant andb => "(Prelude.&&)".
Extract Inlined Constant xorb => "Data.Bits.xor".
+(** Comparisons *)
+
+Extract Inductive comparison => "Prelude.Ordering" [ "Prelude.EQ" "Prelude.LT" "Prelude.GT" ].
+Extract Inductive CompareSpecT => "Prelude.Ordering" [ "Prelude.EQ" "Prelude.LT" "Prelude.GT" ].
+
(** Maybe *)
Extract Inductive option => "Prelude.Maybe" ["Prelude.Just" "Prelude.Nothing"].
@@ -567,53 +580,103 @@ Extract Inductive unit => "()" ["()"].
(** nat *)
-Extract Inlined Constant Nat.add => "(Prelude.+)".
-Extract Inlined Constant Nat.mul => "(Prelude.*)".
-Extract Inlined Constant Nat.max => "Prelude.max".
-Extract Inlined Constant Nat.min => "Prelude.min".
-Extract Inlined Constant Init.Nat.add => "(Prelude.+)".
-Extract Inlined Constant Init.Nat.mul => "(Prelude.*)".
-Extract Inlined Constant Init.Nat.max => "Prelude.max".
-Extract Inlined Constant Init.Nat.min => "Prelude.min".
-Extract Inlined Constant PeanoNat.Nat.add => "(Prelude.+)".
-Extract Inlined Constant PeanoNat.Nat.mul => "(Prelude.*)".
-Extract Inlined Constant PeanoNat.Nat.max => "Prelude.max".
-Extract Inlined Constant PeanoNat.Nat.min => "Prelude.min".
-Extract Inlined Constant Compare_dec.lt_dec => "(Prelude.<)".
-Extract Inlined Constant Compare_dec.leb => "(Prelude.<=)".
-Extract Inlined Constant Compare_dec.le_lt_dec => "(Prelude.<=)".
-Extract Inlined Constant EqNat.beq_nat => "(Prelude.==)".
-Extract Inlined Constant EqNat.eq_nat_decide => "(Prelude.==)".
-Extract Inlined Constant Peano_dec.eq_nat_dec => "(Prelude.==)".
-
-Extract Constant Nat.pred => "(\n -> Prelude.max 0 (Prelude.pred n))".
-Extract Constant Nat.sub => "(\n m -> Prelude.max 0 (n Prelude.- m))".
-Extract Constant Init.Nat.pred => "(\n -> Prelude.max 0 (Prelude.pred n))".
-Extract Constant Init.Nat.sub => "(\n m -> Prelude.max 0 (n Prelude.- m))".
-
-Extract Constant Nat.div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
-Extract Constant Nat.modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
-Extract Constant Init.Nat.div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
-Extract Constant Init.Nat.modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
-
-Extract Inductive nat => "Prelude.Integer" [ "0" "Prelude.succ" ]
- "(\fO fS n -> {- match_on_nat -} if n Prelude.== 0 then fO () else fS (n Prelude.- 1))".
+Require Import Crypto.Experiments.ExtrHaskellNats.
+
+(** positive *)
+Require Import BinPos.
+
+Extract Inductive positive => "Prelude.Integer" [
+ "(\x -> 2 Prelude.* x Prelude.+ 1)"
+ "(\x -> 2 Prelude.* x)"
+ "1" ]
+ "(\fI fO fH n -> {- match_on_positive -}
+ if n Prelude.== 1 then fH () else
+ if Prelude.odd n
+ then fI (n `Prelude.div` 2)
+ else fO (n `Prelude.div` 2))".
+
+Extract Inlined Constant Pos.succ => "(1 Prelude.+)".
+Extract Inlined Constant Pos.add => "(Prelude.+)".
+Extract Inlined Constant Pos.mul => "(Prelude.*)".
+Extract Inlined Constant Pos.pow => "(Prelude.^)".
+Extract Inlined Constant Pos.max => "Prelude.max".
+Extract Inlined Constant Pos.min => "Prelude.min".
+Extract Inlined Constant Pos.gcd => "Prelude.gcd".
+Extract Inlined Constant Pos.land => "(Data.Bits..&.)".
+Extract Inlined Constant Pos.lor => "(Data.Bits..|.)".
+Extract Inlined Constant Pos.compare => "Prelude.compare".
+Extract Inlined Constant Pos.ltb => "(Prelude.<)".
+Extract Inlined Constant Pos.leb => "(Prelude.<=)".
+Extract Inlined Constant Pos.eq_dec => "(Prelude.==)".
+Extract Inlined Constant Pos.eqb => "(Prelude.==)".
+
+(* XXX: unsound -- overflow in fromIntegral *)
+Extract Constant Pos.shiftr => "(\w n -> Data.Bits.shiftR w (Prelude.fromIntegral n))".
+Extract Constant Pos.shiftl => "(\w n -> Data.Bits.shiftL w (Prelude.fromIntegral n))".
+Extract Constant Pos.testbit => "(\w n -> Data.Bits.testBit w (Prelude.fromIntegral n))".
+
+Extract Constant Pos.pred => "(\n -> Prelude.max 1 (Prelude.pred n))".
+Extract Constant Pos.sub => "(\n m -> Prelude.max 1 (n Prelude.- m))".
+
+(** N *)
+
+Extract Inlined Constant N.succ => "(1 Prelude.+)".
+Extract Inlined Constant N.add => "(Prelude.+)".
+Extract Inlined Constant N.mul => "(Prelude.*)".
+Extract Inlined Constant N.pow => "(Prelude.^)".
+Extract Inlined Constant N.max => "Prelude.max".
+Extract Inlined Constant N.min => "Prelude.min".
+Extract Inlined Constant N.gcd => "Prelude.gcd".
+Extract Inlined Constant N.lcm => "Prelude.lcm".
+Extract Inlined Constant N.land => "(Data.Bits..&.)".
+Extract Inlined Constant N.lor => "(Data.Bits..|.)".
+Extract Inlined Constant N.lxor => "Data.Bits.xor".
+Extract Inlined Constant N.compare => "Prelude.compare".
+Extract Inlined Constant N.eq_dec => "(Prelude.==)".
+Extract Inlined Constant N.ltb => "(Prelude.<)".
+Extract Inlined Constant N.leb => "(Prelude.<=)".
+Extract Inlined Constant N.eq_dec => "(Prelude.==)".
+Extract Inlined Constant N.odd => "Prelude.odd".
+Extract Inlined Constant N.even => "Prelude.even".
+
+(* XXX: unsound -- overflow in fromIntegral *)
+Extract Constant N.shiftr => "(\w n -> Data.Bits.shiftR w (Prelude.fromIntegral n))".
+Extract Constant N.shiftl => "(\w n -> Data.Bits.shiftL w (Prelude.fromIntegral n))".
+Extract Constant N.testbit => "(\w n -> Data.Bits.testBit w (Prelude.fromIntegral n))".
+
+Extract Constant N.pred => "(\n -> Prelude.max 0 (Prelude.pred n))".
+Extract Constant N.sub => "(\n m -> Prelude.max 0 (n Prelude.- m))".
+Extract Constant N.div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
+Extract Constant N.modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
+
+Extract Inductive N => "Prelude.Integer" [ "0" "(\x -> x)" ]
+ "(\fO fS n -> {- match_on_N -} if n Prelude.== 0 then fO () else fS (n Prelude.- 1))".
(** Z *)
+Require Import ZArith.BinInt.
-Require Import ZArith.
-Require Import EqNat.
+Extract Inductive Z => "Prelude.Integer" [ "0" "(\x -> x)" "Prelude.negate" ]
+ "(\fO fP fN n -> {- match_on_Z -}
+ if n Prelude.== 0 then fO () else
+ if n Prelude.> 0 then fP n else
+ fN (Prelude.negate n))".
+Extract Inlined Constant Z.succ => "(1 Prelude.+)".
Extract Inlined Constant Z.add => "(Prelude.+)".
Extract Inlined Constant Z.sub => "(Prelude.-)".
+Extract Inlined Constant Z.opp => "Prelude.negate".
Extract Inlined Constant Z.mul => "(Prelude.*)".
+Extract Inlined Constant Z.pow => "(Prelude.^)".
+Extract Inlined Constant Z.pow_pos => "(Prelude.^)".
Extract Inlined Constant Z.max => "Prelude.max".
Extract Inlined Constant Z.min => "Prelude.min".
+Extract Inlined Constant Z.lcm => "Prelude.lcm".
+Extract Inlined Constant Z.land => "(Data.Bits..&.)".
+Extract Inlined Constant Z.pred => "Prelude.pred".
Extract Inlined Constant Z.land => "(Data.Bits..&.)".
Extract Inlined Constant Z.lor => "(Data.Bits..|.)".
-Extract Inlined Constant Z.shiftr => "(\w n -> Data.Bits.shiftR w (Prelude.fromIntegral n))".
-Extract Inlined Constant Z.shiftl => "(\w n -> Data.Bits.shiftL w (Prelude.fromIntegral n))".
-Extract Inlined Constant Z.testbit => "(\w n -> Data.Bits.testBit w (Prelude.fromIntegral n))".
+Extract Inlined Constant Z.lxor => "Data.Bits.xor".
+Extract Inlined Constant Z.compare => "Prelude.compare".
Extract Inlined Constant Z.eq_dec => "(Prelude.==)".
Extract Inlined Constant Z_ge_lt_dec => "(Prelude.>=)".
Extract Inlined Constant Z_gt_le_dec => "(Prelude.>)".
@@ -621,59 +684,127 @@ Extract Inlined Constant Z.ltb => "(Prelude.<)".
Extract Inlined Constant Z.leb => "(Prelude.<=)".
Extract Inlined Constant Z.gtb => "(Prelude.>)".
Extract Inlined Constant Z.geb => "(Prelude.>=)".
+Extract Inlined Constant Z.odd => "Prelude.odd".
+Extract Inlined Constant Z.even => "Prelude.even".
+
+(* XXX: unsound -- overflow in fromIntegral *)
+Extract Constant Z.shiftr => "(\w n -> Data.Bits.shiftR w (Prelude.fromIntegral n))".
+Extract Constant Z.shiftl => "(\w n -> Data.Bits.shiftL w (Prelude.fromIntegral n))".
+Extract Constant Z.testbit => "(\w n -> Data.Bits.testBit w (Prelude.fromIntegral n))".
Extract Constant Z.div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
Extract Constant Z.modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
-Extract Inlined Constant BinIntDef.Z.compare => "Prelude.compare".
-Extract Inductive comparison => "Prelude.Ordering" [ "Prelude.EQ" "Prelude.LT" "Prelude.GT" ].
-Extract Inductive CompareSpecT => "Prelude.Ordering" [ "Prelude.EQ" "Prelude.LT" "Prelude.GT" ].
-
-Extract Inductive positive => "Prelude.Integer" [
- "(\x -> 2 Prelude.* x Prelude.+ 1)"
- "(\x -> 2 Prelude.* x)"
- "1" ]
- "(\fI fO fH n -> {- match_on_positive -}
- if n Prelude.== 1 then fH () else
- if Prelude.odd n
- then fI (n `Prelude.div` 2)
- else fO (n `Prelude.div` 2))".
-
-Extract Inductive Z => "Prelude.Integer" [ "0" "(\x -> x)" "Prelude.negate" ]
- "(\fO fP fN n -> {- match_on_Z -}
- if n Prelude.== 0 then fO () else
- if n Prelude.> 0 then fP n else
- fN (Prelude.negate n))".
+(** Conversions *)
+
+Extract Inlined Constant Z.of_N => "".
+Extract Inlined Constant Z.to_N => "".
+Extract Inlined Constant N.to_nat => "".
+Extract Inlined Constant N.of_nat => "".
+Extract Inlined Constant Z.to_nat => "".
+Extract Inlined Constant Z.of_nat => "".
+Extract Inlined Constant Z.abs_N => "Prelude.abs".
+Extract Inlined Constant Z.abs_nat => "Prelude.abs".
+Extract Inlined Constant Pos.pred_N => "Prelude.pred".
+Extract Inlined Constant Pos.lxor => "Data.Bits.xor".
+
+(** Word *)
+(* do not annotate every bit of a word with the number of bits after it *)
+Extraction Implicit Word.WS [ 2 ].
+Extraction Implicit Word.whd [ 1 ].
+Extraction Implicit Word.wtl [ 1 ].
+Extraction Implicit Word.bitwp [ 2 ].
+Extraction Implicit Word.wand [ 1 ].
+Extraction Implicit Word.wor [ 1 ].
+Extraction Implicit Word.wxor [ 1 ].
+Extraction Implicit Word.wordToN [ 1 ].
+Extraction Implicit Word.wordToNat [ 1 ].
+Extraction Implicit Word.combine [ 1 3 ].
+Extraction Implicit Word.split1 [ 2 ].
+Extraction Implicit Word.split2 [ 2 ].
+Extraction Implicit WordUtil.cast_word [1 2 3].
+Extraction Implicit WordUtil.wfirstn [ 2 4 ].
+Extract Inlined Constant WordUtil.cast_word => "".
(** Let_In *)
Extraction Inline LetIn.Let_In.
+
+(* inlining, primarily to reduce polymorphism *)
+Extraction Inline dec_eq_Z dec_eq_N dec_eq_sig_hprop.
+Extraction Inline Erep SRep ZNWord WordNZ.
+Extraction Inline GF25519.fe25519.
Extraction Inline EdDSARepChange.sign EdDSARepChange.splitSecretPrngCurve.
Extraction Inline SRep_testbit.
+Extraction Inline Crypto.Util.IterAssocOp.iter_op Crypto.Util.IterAssocOp.test_and_op.
Extraction Inline PointEncoding.Kencode_point.
-Extraction Inline ExtendedCoordinates.Extended.coordinates ExtendedCoordinates.Extended.to_twisted ExtendedCoordinates.Extended.from_twisted.
-Extraction Inline CompleteEdwardsCurve.E.coordinates.
-
-(* unused functions *)
-Extraction Inline False_rect False_rec and_rect and_rec.
-Extraction Inline Z.div_eucl.
-Extraction Inline Tuple.from_list'_obligation_1 Tuple.from_list_obligation_1.
-Extraction Inline Tuple.from_list'_obligation_2 Tuple.from_list_obligation_2.
-Extract Inlined Constant Coq.Numbers.Natural.Peano.NPeano.Nat.max_case_strong => "#error unused".
-Extract Inlined Constant Coq.Numbers.Natural.Peano.NPeano.Nat.max_case => "#error unused".
-Extract Inlined Constant Coq.Arith.Max.max_dec => "#error unused".
-Extract Inlined Constant Coq.NArith.BinNat.N.max_dec => "#error unused".
-Extract Inlined Constant Coq.Numbers.Natural.Peano.NPeano.Nat.max_dec => "#error unused".
-Extract Inlined Constant Coq.Arith.PeanoNat.Nat.max_dec => "#error unused".
-Extract Inlined Constant Coq.PArith.BinPos.Pos.max_dec => "#error unused".
-Extract Inlined Constant Coq.NArith.BinNat.N.Private_Dec.max_dec => "#error unused".
-Extract Inlined Constant Coq.Numbers.Natural.Peano.NPeano.Nat.Private_Dec.max_dec => "#error unused".
-Extract Inlined Constant Coq.Arith.PeanoNat.Nat.Private_Dec.max_dec => "#error unused".
-Extract Inlined Constant Coq.PArith.BinPos.Pos.Private_Dec.max_dec => "#error unused".
-Extract Inlined Constant Coq.ZArith.BinInt.Z.Private_Dec.max_dec => "#error unused".
-Extract Inlined Constant Coq.ZArith.BinInt.Z.max_dec => "#error unused".
-Extract Inlined Constant Nat.divmod => "#error unused".
-Extract Inlined Constant Coq.NArith.BinNat.N.sqrt_up => "#error unused".
-Extract Inlined Constant Coq.Numbers.Natural.Peano.NPeano.Nat.sqrt_up => "#error unused".
-Extract Inlined Constant Coq.Arith.PeanoNat.Nat.sqrt_up => "#error unused".
-Extract Inlined Constant Coq.ZArith.BinInt.Z.sqrt_up => "#error unused".
+Extraction Inline ExtendedCoordinates.Extended.point ExtendedCoordinates.Extended.coordinates ExtendedCoordinates.Extended.to_twisted ExtendedCoordinates.Extended.from_twisted ExtendedCoordinates.Extended.add_coordinates ExtendedCoordinates.Extended.add ExtendedCoordinates.Extended.opp ExtendedCoordinates.Extended.zero. (* ExtendedCoordinates.Extended.zero could be precomputed *)
+Extraction Inline CompleteEdwardsCurve.E.coordinates CompleteEdwardsCurve.E.zero.
+
(* Recursive Extraction sign. *)
+ (* most of the code we want seems to be below [eq_dec1] and there is other stuff above that *)
+ (* TODO: remove branching from [sRep] functions *)
+
+(* fragment of output:
+
+sign :: Word -> Word -> Prelude.Integer -> Word -> Word
+sign pk sk mlen msg =
+ let {
+ sp = let {hsk = h b sk} in
+ (,)
+ (sRepDecModLShort
+ (combine n (clearlow n c (wfirstn n ((Prelude.+) b b) hsk)) (Prelude.succ 0)
+ (wones (Prelude.succ 0)))) (split2 b b hsk)}
+ in
+ let {r = sRepDecModL (h ((Prelude.+) b mlen) (combine b (Prelude.snd sp) mlen msg))} in
+ let {r0 = sRepERepMul r eRepB} in
+ combine b (eRepEnc r0) b
+ (sRepEnc
+ (sRepAdd r
+ (sRepMul
+ (sRepDecModL
+ (h ((Prelude.+) b ((Prelude.+) b mlen))
+ (combine b (eRepEnc r0) ((Prelude.+) b mlen) (combine b pk mlen msg)))) (Prelude.fst sp))))
+
+sRepERepMul :: SRep0 -> Erep -> Erep
+sRepERepMul sc a =
+ Prelude.snd
+ (funexp (\state ->
+ case state of {
+ (,) i acc ->
+ let {acc2 = erepAdd acc acc} in
+ let {acc2a = erepAdd a acc2} in
+ (\fO fS n -> {- match_on_nat -} if n Prelude.== 0 then fO () else fS (n Prelude.- 1))
+ (\_ -> (,) 0
+ acc)
+ (\i' -> (,) i'
+ (eRepSel ((\w n -> Data.Bits.testBit w (Prelude.fromIntegral n)) sc (of_nat i')) acc2 acc2a))
+ i}) ((,) ll
+ (case ((,) zero_ one_) of {
+ (,) x y -> (,) ((,) ((,) x y) one_) (mul3 x y)})) ll)
+
+erepAdd :: (Point0 Fe25519) -> (Point0 Fe25519) -> Point0 Fe25519
+erepAdd p q =
+ case p of {
+ (,) y t1 ->
+ case y of {
+ (,) y0 z1 ->
+ case y0 of {
+ (,) x1 y1 ->
+ case q of {
+ (,) y2 t2 ->
+ case y2 of {
+ (,) y3 z2 ->
+ case y3 of {
+ (,) x2 y4 ->
+ let {a = mul3 (sub2 y1 x1) (sub2 y4 x2)} in
+ let {b0 = mul3 (add2 y1 x1) (add2 y4 x2)} in
+ let {c0 = mul3 (mul3 t1 twice_d) t2} in
+ let {d = mul3 z1 (add2 z2 z2)} in
+ let {e = sub2 b0 a} in
+ let {f = sub2 d c0} in
+ let {g = add2 d c0} in
+ let {h0 = add2 b0 a} in
+ let {x3 = mul3 e f} in
+ let {y5 = mul3 g h0} in
+ let {t3 = mul3 e h0} in let {z3 = mul3 f g} in (,) ((,) ((,) x3 y5) z3) t3}}}}}}
+*)
diff --git a/src/Experiments/ExtrHaskellNats.v b/src/Experiments/ExtrHaskellNats.v
new file mode 100644
index 000000000..ef9fd06d9
--- /dev/null
+++ b/src/Experiments/ExtrHaskellNats.v
@@ -0,0 +1,94 @@
+(** * Extraction Directives for [nat] in Haskell *)
+(** [nat] is really complicated, so we jump through many hoops to get
+ code that compiles in 8.4 and 8.5 at the same time. *)
+Require Coq.Numbers.Natural.Peano.NPeano.
+Require Coq.Arith.Compare_dec Coq.Arith.EqNat Coq.Arith.Peano_dec.
+
+Extract Inductive nat => "Prelude.Integer" [ "0" "Prelude.succ" ]
+ "(\fO fS n -> {- match_on_nat -} if n Prelude.== 0 then fO () else fS (n Prelude.- 1))".
+
+
+(** We rely on the fact that Coq forbids masking absolute names. Hopefully we can drop support for 8.4 before this is changed. *)
+Module Coq.
+ Module M. Export NPeano.Nat. End M.
+ Module Init.
+ Module Nat.
+ Export M.
+ End Nat.
+ End Init.
+ Module Numbers.
+ Module Natural.
+ Module Peano.
+ Module NPeano.
+ Module Nat.
+ Export M.
+ End Nat.
+ End NPeano.
+ End Peano.
+ End Natural.
+ End Numbers.
+ Module Arith.
+ Module PeanoNat.
+ Module Nat.
+ Export M.
+ End Nat.
+ End PeanoNat.
+ End Arith.
+End Coq.
+
+Module Export Import_NPeano_Nat.
+ Import Coq.Numbers.Natural.Peano.NPeano.Nat.
+
+ Extract Inlined Constant add => "(Prelude.+)".
+ Extract Inlined Constant mul => "(Prelude.*)".
+ Extract Inlined Constant pow => "(Prelude.^)".
+ Extract Inlined Constant max => "Prelude.max".
+ Extract Inlined Constant min => "Prelude.min".
+ Extract Inlined Constant gcd => "Prelude.gcd".
+ Extract Inlined Constant lcm => "Prelude.lcm".
+ Extract Inlined Constant land => "(Data.Bits..&.)".
+ Extract Inlined Constant compare => "Prelude.compare".
+ Extract Inlined Constant ltb => "(Prelude.<)".
+ Extract Inlined Constant leb => "(Prelude.<=)".
+ Extract Inlined Constant eqb => "(Prelude.==)".
+ Extract Inlined Constant odd => "Prelude.odd".
+ Extract Inlined Constant even => "Prelude.even".
+ Extract Constant pred => "(\n -> Prelude.max 0 (Prelude.pred n))".
+ Extract Constant sub => "(\n m -> Prelude.max 0 (n Prelude.- m))".
+ Extract Constant div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
+ Extract Constant modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
+End Import_NPeano_Nat.
+
+
+Module Export Import_Init_Nat.
+ Import Coq.Init.Nat.
+
+ Extract Inlined Constant add => "(Prelude.+)".
+ Extract Inlined Constant mul => "(Prelude.*)".
+ Extract Inlined Constant max => "Prelude.max".
+ Extract Inlined Constant min => "Prelude.min".
+ Extract Constant pred => "(\n -> Prelude.max 0 (Prelude.pred n))".
+ Extract Constant sub => "(\n m -> Prelude.max 0 (n Prelude.- m))".
+
+ Extract Constant div => "(\n m -> if m Prelude.== 0 then 0 else Prelude.div n m)".
+ Extract Constant modulo => "(\n m -> if m Prelude.== 0 then 0 else Prelude.mod n m)".
+End Import_Init_Nat.
+
+
+Module Export Import_PeanoNat_Nat.
+ Import Coq.Arith.PeanoNat.Nat.
+
+ Extract Inlined Constant add => "(Prelude.+)".
+ Extract Inlined Constant mul => "(Prelude.*)".
+ Extract Inlined Constant max => "Prelude.max".
+ Extract Inlined Constant min => "Prelude.min".
+ Extract Inlined Constant compare => "Prelude.compare".
+End Import_PeanoNat_Nat.
+
+Extract Inlined Constant Compare_dec.nat_compare_alt => "Prelude.compare".
+Extract Inlined Constant Compare_dec.lt_dec => "(Prelude.<)".
+Extract Inlined Constant Compare_dec.leb => "(Prelude.<=)".
+Extract Inlined Constant Compare_dec.le_lt_dec => "(Prelude.<=)".
+Extract Inlined Constant EqNat.beq_nat => "(Prelude.==)".
+Extract Inlined Constant EqNat.eq_nat_decide => "(Prelude.==)".
+Extract Inlined Constant Peano_dec.eq_nat_dec => "(Prelude.==)".
diff --git a/src/ModularArithmetic/ModularBaseSystem.v b/src/ModularArithmetic/ModularBaseSystem.v
index 5c0d143c2..615bd832b 100644
--- a/src/ModularArithmetic/ModularBaseSystem.v
+++ b/src/ModularArithmetic/ModularBaseSystem.v
@@ -82,10 +82,10 @@ Section ModularBaseSystem.
Definition eq (x y : digits) : Prop := decode x = decode y.
- Definition freeze (x : digits) : digits :=
- from_list (freeze [[x]]) (length_freeze length_to_list).
+ Definition freeze B (x : digits) : digits :=
+ from_list (freeze B [[x]]) (length_freeze length_to_list).
- Definition eqb (x y : digits) : bool := fieldwiseb Z.eqb (freeze x) (freeze y).
+ Definition eqb B (x y : digits) : bool := fieldwiseb Z.eqb (freeze B x) (freeze B y).
(* Note : both of the following square root definitions will produce garbage output if the input is
not square mod [modulus]. The caller should either provably only call them with square input,
@@ -97,10 +97,10 @@ Section ModularBaseSystem.
(* sqrt_5mod8 is parameterized over implementation of [mul] and [pow] because it relies on bounds-checking
for these two functions, which is much easier for simplified implementations than the more generalized
ones defined here. *)
- Definition sqrt_5mod8 mul_ pow_ (chain : list (nat * nat))
+ Definition sqrt_5mod8 B mul_ pow_ (chain : list (nat * nat))
(chain_correct : fold_chain 0%N N.add chain (1%N :: nil) = Z.to_N (modulus / 8 + 1))
(sqrt_minus1 x : digits) : digits :=
- let b := pow_ x chain in if eqb (mul_ b b) x then b else mul_ sqrt_minus1 b.
+ let b := pow_ x chain in if eqb B (mul_ b b) x then b else mul_ sqrt_minus1 b.
Import Morphisms.
Global Instance eq_Equivalence : Equivalence eq.
@@ -108,6 +108,10 @@ Section ModularBaseSystem.
split; cbv [eq]; repeat intro; congruence.
Qed.
+ Definition select B (b : Z) (x y : digits) :=
+ add (map (Z.land (neg B b)) x)
+ (map (Z.land (neg B (Z.lxor b 1))) x).
+
Context {target_widths} (target_widths_nonneg : forall x, In x target_widths -> 0 <= x)
(bits_eq : sum_firstn limb_widths (length limb_widths) =
sum_firstn target_widths (length target_widths)).
diff --git a/src/ModularArithmetic/ModularBaseSystemList.v b/src/ModularArithmetic/ModularBaseSystemList.v
index 6d0848151..e64ed5d0f 100644
--- a/src/ModularArithmetic/ModularBaseSystemList.v
+++ b/src/ModularArithmetic/ModularBaseSystemList.v
@@ -8,6 +8,7 @@ Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParams.
Require Import Crypto.ModularArithmetic.PseudoMersenneBaseParamProofs.
Require Import Crypto.ModularArithmetic.ExtendedBaseVector.
Require Import Crypto.Tactics.VerdiTactics.
+Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.Notations.
Require Import Crypto.ModularArithmetic.Pow2Base.
Require Import Crypto.ModularArithmetic.Conversion.
@@ -51,28 +52,35 @@ Section Defs.
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.leb (modulus_digits [0]) (us [0])) acc
- | S i' => ge_modulus' us (andb (Z.eqb (modulus_digits [i]) (us [i])) acc) i'
+ Fixpoint ge_modulus' {A} (f : Z -> A) us (result : Z) i :=
+ dlet r := result in
+ match i return A with
+ | O => dlet x := if Z.leb (modulus_digits [0]) (us [0])
+ then r
+ else 0 in f x
+ | S i' => ge_modulus' f us
+ (if Z.eqb (modulus_digits [i]) (us [i])
+ then r
+ else 0) i'
end.
- Definition ge_modulus us := ge_modulus' us true (length limb_widths - 1)%nat.
+ Definition ge_modulus us := ge_modulus' id us 1 (length limb_widths - 1)%nat.
+
+ (* analagous to NEG assembly instruction on an integer that is 0 or 1:
+ neg 1 = 2^64 - 1 (on 64-bit; 2^32-1 on 32-bit, etc.)
+ neg 0 = 0 *)
+ Definition neg (int_width : Z) (b : Z) := if b =? 1 then Z.ones int_width else 0.
- Definition conditional_subtract_modulus (us : digits) (cond : bool) :=
- let and_term := if cond then max_ones else 0 in
+ Definition conditional_subtract_modulus int_width (us : digits) (cond : Z) :=
(* [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).
+ map2 (fun x y => x - y) us (map (Z.land (neg int_width cond)) modulus_digits).
- Definition freeze (us : digits) : digits :=
+ Definition freeze int_width (us : digits) : digits :=
let us' := carry_full (carry_full (carry_full us)) in
- conditional_subtract_modulus us' (ge_modulus us').
+ conditional_subtract_modulus int_width us' (ge_modulus us').
Context {target_widths} (target_widths_nonneg : forall x, In x target_widths -> 0 <= x)
(bits_eq : sum_firstn limb_widths (length limb_widths) =
@@ -86,4 +94,4 @@ Section Defs.
limb_widths limb_widths_nonneg
(Z.eq_le_incl _ _ (Z.eq_sym bits_eq)).
-End Defs.
+End Defs. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemListProofs.v b/src/ModularArithmetic/ModularBaseSystemListProofs.v
index 93b39e89a..23ec30cf7 100644
--- a/src/ModularArithmetic/ModularBaseSystemListProofs.v
+++ b/src/ModularArithmetic/ModularBaseSystemListProofs.v
@@ -110,10 +110,11 @@ Section LengthProofs.
rewrite encode'_spec, encode'_length;
auto using encode'_length, limb_widths_nonneg, Nat.eq_le_incl, base_from_limb_widths_length.
Qed.
+ Hint Rewrite @length_modulus_digits : distr_length.
- Lemma length_conditional_subtract_modulus {u cond} :
+ Lemma length_conditional_subtract_modulus {int_width u cond} :
length u = length limb_widths
- -> length (conditional_subtract_modulus u cond) = length limb_widths.
+ -> length (conditional_subtract_modulus int_width u cond) = length limb_widths.
Proof.
intros; unfold conditional_subtract_modulus.
rewrite map2_length, map_length, length_modulus_digits.
@@ -121,9 +122,9 @@ Section LengthProofs.
Qed.
Hint Rewrite @length_conditional_subtract_modulus : distr_length.
- Lemma length_freeze {u} :
+ Lemma length_freeze {int_width u} :
length u = length limb_widths
- -> length (freeze u) = length limb_widths.
+ -> length (freeze int_width u) = length limb_widths.
Proof.
intros; unfold freeze; repeat autorewrite with distr_length; congruence.
Qed.
@@ -285,27 +286,41 @@ Section ModulusComparisonProofs.
reflexivity.
Qed.
- Lemma ge_modulus'_false : forall us i,
- ge_modulus' us false i = false.
+ Lemma ge_modulus'_0 : forall {A} f us i,
+ ge_modulus' (A := A) f us 0 i = f 0.
Proof.
- induction i; intros; simpl; rewrite Bool.andb_false_r; auto.
+ induction i; intros; simpl; break_if; auto.
+ Qed.
+
+ Lemma ge_modulus'_01 : forall {A} f us i b,
+ (b = 0 \/ b = 1) ->
+ (ge_modulus' (A := A) f us b i = f 0 \/ ge_modulus' (A := A) f us b i = f 1).
+ Proof.
+ induction i; intros;
+ try intuition (subst; cbv [ge_modulus' LetIn.Let_In]; break_if; tauto).
+ simpl; cbv [LetIn.Let_In].
+ break_if; apply IHi; tauto.
+ Qed.
+
+ Lemma ge_modulus_01 : forall us,
+ (ge_modulus us = 0 \/ ge_modulus us = 1).
+ Proof.
+ cbv [ge_modulus]; intros; apply ge_modulus'_01; tauto.
Qed.
Lemma ge_modulus'_true_digitwise : forall us,
length us = length limb_widths ->
- forall i, (i < length us)%nat -> ge_modulus' us true i = true ->
+ forall i, (i < length us)%nat -> ge_modulus' id us 1 i = 1 ->
forall j, (j <= i)%nat ->
nth_default 0 modulus_digits j <= nth_default 0 us j.
Proof.
induction i;
repeat match goal with
| |- _ => progress intros; simpl in *
- | |- _ => rewrite ge_modulus'_false in *
+ | |- _ => progress cbv [LetIn.Let_In] in *
+ | |- _ =>erewrite (ge_modulus'_0 (@id Z)) in *
| H : (?x <= 0)%nat |- _ => progress replace x with 0%nat in * by omega
- | H : (?b && true)%bool = true |- _ => let A:= fresh "H" in
- rewrite Bool.andb_true_r in H; case_eq b; intro A; rewrite A in H
- | H : ge_modulus' _ (?b && true)%bool _ = true |- _ => let A:= fresh "H" in
- rewrite Bool.andb_true_r in H; case_eq b; intro A; rewrite A in H
+ | |- _ => break_if
| |- _ => discriminate
| |- _ => solve [rewrite ?Z.leb_le, ?Z.eqb_eq in *; omega]
end.
@@ -316,35 +331,39 @@ Section ModulusComparisonProofs.
Lemma ge_modulus'_compare' : forall us, length us = length limb_widths -> bounded limb_widths us ->
forall i, (i < length limb_widths)%nat ->
- (ge_modulus' us true i = false <-> compare' us modulus_digits (S i) = Lt).
+ (ge_modulus' id us 1 i = 0 <-> compare' us modulus_digits (S i) = Lt).
Proof.
induction i;
repeat match goal with
- | |- _ => progress intros
- | |- _ => progress (simpl compare' in *)
+ | |- _ => progress (intros; cbv [LetIn.Let_In id])
+ | |- _ => progress (simpl compare' in * )
| |- _ => progress specialize_by omega
- | |- _ => progress rewrite ?Z.compare_eq_iff,
- ?Z.compare_gt_iff, ?Z.compare_lt_iff in *
- | |- appcontext[ge_modulus' _ _ 0] =>
+ | |- _ => (progress rewrite ?Z.compare_eq_iff,
+ ?Z.compare_gt_iff, ?Z.compare_lt_iff in * )
+ | |- appcontext[ge_modulus' _ _ _ 0] =>
cbv [ge_modulus']
- | |- appcontext[ge_modulus' _ _ (S _)] =>
- unfold ge_modulus'; fold ge_modulus'
+ | |- appcontext[ge_modulus' _ _ _ (S _)] =>
+ unfold ge_modulus'; fold (ge_modulus' (@id Z))
| |- _ => break_if
| |- _ => rewrite Nat.sub_0_r
- | |- _ => rewrite ge_modulus'_false
+ | |- _ => rewrite (ge_modulus'_0 (@id Z))
| |- _ => rewrite Bool.andb_true_r
| |- _ => rewrite Z.leb_compare; break_match
| |- _ => rewrite Z.eqb_compare; break_match
+ | |- _ => (rewrite Z.leb_le in * )
+ | |- _ => (rewrite Z.leb_gt in * )
+ | |- _ => (rewrite Z.eqb_eq in * )
+ | |- _ => (rewrite Z.eqb_neq in * )
| |- _ => split; (congruence || omega)
| |- _ => assumption
- end;
- pose proof (bounded_le_modulus_digits c_upper_bound us (S i));
- specialize_by (auto || omega); omega.
+ end;
+ pose proof (bounded_le_modulus_digits c_upper_bound us (S i));
+ specialize_by (auto || omega); split; (congruence || omega).
Qed.
Lemma ge_modulus_spec : forall u, length u = length limb_widths ->
bounded limb_widths u ->
- (ge_modulus u = false <-> 0 <= BaseSystem.decode base u < modulus).
+ (ge_modulus u = 0 <-> 0 <= BaseSystem.decode base u < modulus).
Proof.
cbv [ge_modulus]; intros.
assert (0 < length limb_widths)%nat
@@ -365,6 +384,8 @@ End ModulusComparisonProofs.
Section ConditionalSubtractModulusProofs.
Context `{prm :PseudoMersenneBaseParams}
+ (* B is machine integer width (e.g. 32, 64) *)
+ {B} (B_pos : 0 < B) (B_compat : forall w, In w limb_widths -> w <= B)
(c_upper_bound : c - 1 < 2 ^ nth_default 0 limb_widths 0)
(lt_1_length_limb_widths : (1 < length limb_widths)%nat).
Local Notation base := (base_from_limb_widths limb_widths).
@@ -386,24 +407,33 @@ Section ConditionalSubtractModulusProofs.
simpl; f_equal; auto using in_eq, in_cons.
Qed.
- Lemma map_land_max_ones : forall us, length us = length limb_widths ->
- bounded limb_widths us -> map (Z.land max_ones) us = us.
+ Lemma bounded_digit_fits : forall us,
+ length us = length limb_widths -> bounded limb_widths us ->
+ forall x, In x us -> 0 <= x < 2 ^ B.
Proof.
- intros; apply map_id_strong; intros ? HIn.
- rewrite Z.land_comm.
- cbv [max_ones].
- rewrite Z.land_ones by apply Z.le_fold_right_max_initial.
- apply Z.mod_small.
- apply In_nth with (d := 0) in HIn.
- destruct HIn as [i HIn]; destruct HIn; subst.
- rewrite bounded_iff in H0.
- specialize (H0 i).
+ intros.
+ let i := fresh "i" in
+ match goal with H : In ?x ?us, Hb : bounded _ _ |- _ =>
+ apply In_nth with (d := 0) in H; destruct H as [i [? ?] ];
+ rewrite bounded_iff in Hb; specialize (Hb i);
+ assert (2 ^ nth i limb_widths 0 <= 2 ^ B) by
+ (apply Z.pow_le_mono_r; try apply B_compat, nth_In; omega) end.
rewrite !nth_default_eq in *.
- split; try omega.
- eapply Z.lt_le_trans; try intuition eassumption.
- apply Z.pow_le_mono_r; try omega.
- apply Z.le_fold_right_max; eauto.
- apply nth_In. omega.
+ omega.
+ Qed.
+
+ Lemma map_land_max_ones : forall us,
+ length us = length limb_widths ->
+ bounded limb_widths us -> map (Z.land (Z.ones B)) us = us.
+ Proof.
+ repeat match goal with
+ | |- _ => progress intros
+ | |- _ => apply map_id_strong
+ | |- appcontext[Z.ones ?n &' ?x] => rewrite (Z.land_comm _ x);
+ rewrite Z.land_ones by omega
+ | |- _ => apply Z.mod_small
+ | |- _ => solve [eauto using bounded_digit_fits]
+ end.
Qed.
Lemma map_land_zero : forall us, map (Z.land 0) us = zeros (length us).
@@ -411,32 +441,35 @@ Section ConditionalSubtractModulusProofs.
induction us; boring.
Qed.
- Lemma conditional_subtract_modulus_spec : forall u cond,
+ Hint Rewrite @length_modulus_digits @length_zeros : distr_length.
+ Lemma conditional_subtract_modulus_spec : forall u cond
+ (cond_01 : cond = 0 \/ cond = 1),
length u = length limb_widths ->
- BaseSystem.decode base (conditional_subtract_modulus u cond) =
- BaseSystem.decode base u - (if cond then 1 else 0) * modulus.
+ BaseSystem.decode base (conditional_subtract_modulus B u cond) =
+ BaseSystem.decode base u - cond * modulus.
Proof.
repeat match goal with
- | |- _ => progress (cbv [conditional_subtract_modulus]; intros)
+ | |- _ => progress (cbv [conditional_subtract_modulus neg]; intros)
+ | |- _ => destruct cond_01; subst
| |- _ => break_if
| |- _ => rewrite map_land_max_ones by auto using bounded_modulus_digits
| |- _ => rewrite map_land_zero
- | |- _ => rewrite map2_sub_eq
- by (rewrite ?length_modulus_digits, ?length_zeros; congruence)
+ | |- _ => rewrite map2_sub_eq by distr_length
| |- _ => rewrite sub_rep by auto
| |- _ => rewrite zeros_rep
| |- _ => rewrite decode_modulus_digits by auto
| |- _ => f_equal; ring
+ | |- _ => discriminate
end.
Qed.
Lemma conditional_subtract_modulus_preserves_bounded : forall u,
length u = length limb_widths ->
bounded limb_widths u ->
- bounded limb_widths (conditional_subtract_modulus u (ge_modulus u)).
+ bounded limb_widths (conditional_subtract_modulus B u (ge_modulus u)).
Proof.
repeat match goal with
- | |- _ => progress (cbv [conditional_subtract_modulus]; intros)
+ | |- _ => progress (cbv [conditional_subtract_modulus neg]; intros)
| |- _ => unique pose proof bounded_modulus_digits
| |- _ => rewrite map_land_max_ones by auto using bounded_modulus_digits
| |- _ => rewrite map_land_zero
@@ -455,11 +488,12 @@ Section ConditionalSubtractModulusProofs.
| |- _ => omega
end.
cbv [ge_modulus] in Heqb.
+ rewrite Z.eqb_eq in *.
apply ge_modulus'_true_digitwise with (j := i) in Heqb; auto; omega.
Qed.
Lemma bounded_mul2_modulus : forall u, length u = length limb_widths ->
- bounded limb_widths u -> ge_modulus u = true ->
+ bounded limb_widths u -> ge_modulus u = 1 ->
modulus <= BaseSystem.decode base u < 2 * modulus.
Proof.
intros.
@@ -494,16 +528,16 @@ Section ConditionalSubtractModulusProofs.
Lemma conditional_subtract_lt_modulus : forall u,
length u = length limb_widths ->
bounded limb_widths u ->
- ge_modulus (conditional_subtract_modulus u (ge_modulus u)) = false.
+ ge_modulus (conditional_subtract_modulus B u (ge_modulus u)) = 0.
Proof.
intros.
- rewrite ge_modulus_spec by auto using length_conditional_subtract_modulus,
- conditional_subtract_modulus_preserves_bounded.
+ rewrite ge_modulus_spec by auto using length_conditional_subtract_modulus, conditional_subtract_modulus_preserves_bounded.
+ pose proof (ge_modulus_01 u) as Hgm01.
rewrite conditional_subtract_modulus_spec by auto.
- break_if.
- + pose proof (bounded_mul2_modulus u); specialize_by auto.
+ destruct Hgm01 as [Hgm0 | Hgm1]; rewrite ?Hgm0, ?Hgm1.
+ + apply ge_modulus_spec in Hgm0; auto.
omega.
- + apply ge_modulus_spec in Heqb; auto.
+ + pose proof (bounded_mul2_modulus u); specialize_by auto.
omega.
Qed.
End ConditionalSubtractModulusProofs. \ No newline at end of file
diff --git a/src/ModularArithmetic/ModularBaseSystemOpt.v b/src/ModularArithmetic/ModularBaseSystemOpt.v
index ff1dd87dd..1117229d1 100644
--- a/src/ModularArithmetic/ModularBaseSystemOpt.v
+++ b/src/ModularArithmetic/ModularBaseSystemOpt.v
@@ -49,7 +49,6 @@ 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 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 sum_firstn_opt {A} := Eval compute in (@sum_firstn A).
Definition zeros_opt := Eval compute in (@zeros).
@@ -954,18 +953,16 @@ Section Canonicalization.
-> carry_full_3_opt_cps f us = f (carry_full (carry_full (carry_full us)))
:= proj2_sig (carry_full_3_opt_cps_sig f us).
- Definition conditional_subtract_modulus_opt_sig (f : list Z) (cond : bool) :
- { g | g = conditional_subtract_modulus f cond}.
+ Definition conditional_subtract_modulus_opt_sig (f : list Z) (cond : Z) :
+ { g | g = conditional_subtract_modulus int_width f cond}.
Proof.
eexists.
cbv [conditional_subtract_modulus].
- match goal with |- appcontext[if cond then ?a else ?b] =>
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 (if cond then a else b) in RHS) with ?RHSf _ => RHSf end in
- change (LHS = Let_In (if cond then a else b) RHSf) end.
+ let RHSf := match (eval pattern (neg int_width cond) in RHS) with ?RHSf _ => RHSf end in
+ change (LHS = Let_In (neg int_width cond) RHSf).
cbv [map2 map].
- change @max_ones with max_ones_opt.
reflexivity.
Defined.
@@ -973,39 +970,50 @@ Section Canonicalization.
:= Eval cbv [proj1_sig conditional_subtract_modulus_opt_sig] in proj1_sig (conditional_subtract_modulus_opt_sig f cond).
Definition conditional_subtract_modulus_opt_correct f cond
- : conditional_subtract_modulus_opt f cond = conditional_subtract_modulus f cond
+ : conditional_subtract_modulus_opt f cond = conditional_subtract_modulus int_width f cond
:= Eval cbv [proj2_sig conditional_subtract_modulus_opt_sig] in proj2_sig (conditional_subtract_modulus_opt_sig f cond).
+ Lemma ge_modulus'_cps : forall {A} (f : Z -> A) (us : list Z) i b,
+ f (ge_modulus' id us b i) = ge_modulus' f us b i.
+ Proof.
+ induction i; intros; simpl; cbv [Let_In]; break_if; try reflexivity;
+ apply IHi.
+ Qed.
+
Definition ge_modulus_opt_sig (us : list Z) :
- { b : bool | b = ModularBaseSystemList.ge_modulus us }.
+ { a : Z | a = ge_modulus us}.
Proof.
eexists.
- cbv beta iota delta [ge_modulus ge_modulus'].
+ cbv [ge_modulus ge_modulus'].
change length with length_opt.
change nth_default with @nth_default_opt.
change minus with minus_opt.
reflexivity.
Defined.
- Definition ge_modulus_opt us : bool
+ Definition ge_modulus_opt us : Z
:= Eval cbv [proj1_sig ge_modulus_opt_sig] in proj1_sig (ge_modulus_opt_sig us).
Definition ge_modulus_opt_correct us :
- ge_modulus_opt us = ge_modulus us
+ ge_modulus_opt us= ge_modulus us
:= Eval cbv [proj2_sig ge_modulus_opt_sig] in proj2_sig (ge_modulus_opt_sig us).
Definition freeze_opt_sig (us : list Z) :
{ b : list Z | length us = length limb_widths
- -> b = ModularBaseSystemList.freeze us }.
+ -> b = ModularBaseSystemList.freeze int_width us }.
Proof.
eexists.
cbv [ModularBaseSystemList.freeze].
rewrite <-conditional_subtract_modulus_opt_correct.
intros.
+ cbv [ge_modulus].
+ rewrite ge_modulus'_cps.
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) by auto.
+ cbv [carry_full_3_opt_cps carry_full_opt_cps carry_sequence_opt_cps].
+ cbv [ge_modulus'].
cbv beta iota delta [ge_modulus ge_modulus'].
change length with length_opt.
change nth_default with @nth_default_opt.
@@ -1019,7 +1027,7 @@ Section Canonicalization.
Definition freeze_opt_correct us
: length us = length limb_widths
- -> freeze_opt us = ModularBaseSystemList.freeze us
+ -> freeze_opt us = ModularBaseSystemList.freeze int_width us
:= proj2_sig (freeze_opt_sig us).
End Canonicalization.
@@ -1061,15 +1069,16 @@ Section SquareRoots.
End SquareRoot3mod4.
Import Morphisms.
- Global Instance eqb_Proper : Proper (eq ==> eq ==> Logic.eq) ModularBaseSystem.eqb. Admitted.
+ Global Instance eqb_Proper : Proper (Logic.eq ==> eq ==> eq ==> Logic.eq) ModularBaseSystem.eqb. Admitted.
Section SquareRoot5mod8.
Context {ec : ExponentiationChain (modulus / 8 + 1)}.
Context (sqrt_m1 : digits) (sqrt_m1_correct : rep (mul sqrt_m1 sqrt_m1) (F.opp 1%F)).
+ Context {int_width} (preconditions : freezePreconditions prm int_width).
Definition sqrt_5mod8_opt_sig (us : digits) :
{ vs : digits |
- eq vs (sqrt_5mod8 (carry_mul_opt k_ c_) (pow_opt k_ c_ one_) chain chain_correct sqrt_m1 us)}.
+ eq vs (sqrt_5mod8 int_width (carry_mul_opt k_ c_) (pow_opt k_ c_ one_) chain chain_correct sqrt_m1 us)}.
Proof.
eexists; cbv [sqrt_5mod8].
let LHS := match goal with |- eq ?LHS ?RHS => LHS end in
@@ -1083,7 +1092,7 @@ Section SquareRoots.
proj1_sig (sqrt_5mod8_opt_sig us).
Definition sqrt_5mod8_opt_correct us
- : eq (sqrt_5mod8_opt us) (ModularBaseSystem.sqrt_5mod8 _ _ chain chain_correct sqrt_m1 us)
+ : eq (sqrt_5mod8_opt us) (ModularBaseSystem.sqrt_5mod8 int_width _ _ chain chain_correct sqrt_m1 us)
:= Eval cbv [proj2_sig sqrt_5mod8_opt_sig] in proj2_sig (sqrt_5mod8_opt_sig us).
End SquareRoot5mod8.
diff --git a/src/ModularArithmetic/ModularBaseSystemProofs.v b/src/ModularArithmetic/ModularBaseSystemProofs.v
index f8ad0969d..9a07e8ec0 100644
--- a/src/ModularArithmetic/ModularBaseSystemProofs.v
+++ b/src/ModularArithmetic/ModularBaseSystemProofs.v
@@ -833,7 +833,7 @@ Section CanonicalizationProofs.
then 0
else (2 ^ B) >> (limb_widths [pred n]))).
Local Notation minimal_rep u := ((bounded limb_widths (to_list (length limb_widths) u))
- /\ (ge_modulus (to_list _ u) = false)).
+ /\ (ge_modulus (to_list _ u) = 0)).
Lemma decode_bitwise_eq_iff : forall u v, minimal_rep u -> minimal_rep v ->
(fieldwise Logic.eq u v <->
@@ -896,7 +896,7 @@ Section CanonicalizationProofs.
Qed.
Lemma minimal_rep_freeze : forall u, initial_bounds u ->
- minimal_rep (freeze u).
+ minimal_rep (freeze B u).
Proof.
repeat match goal with
| |- _ => progress (cbv [freeze ModularBaseSystemList.freeze])
@@ -907,12 +907,12 @@ Section CanonicalizationProofs.
| |- _ => apply conditional_subtract_lt_modulus
| |- _ => apply conditional_subtract_modulus_preserves_bounded
| |- bounded _ (carry_full _) => apply bounded_iff
- | |- _ => solve [auto using lt_1_length_limb_widths, length_carry_full, length_to_list]
+ | |- _ => solve [auto using B_pos, B_compat, lt_1_length_limb_widths, length_carry_full, length_to_list]
end.
Qed.
Lemma freeze_decode : forall u,
- BaseSystem.decode base (to_list _ (freeze u)) mod modulus =
+ BaseSystem.decode base (to_list _ (freeze B u)) mod modulus =
BaseSystem.decode base (to_list _ u) mod modulus.
Proof.
repeat match goal with
@@ -922,7 +922,7 @@ Section CanonicalizationProofs.
| |- _ => rewrite Z.mod_add by (pose proof prime_modulus; prime_bound)
| |- _ => rewrite to_list_from_list
| |- _ => rewrite conditional_subtract_modulus_spec by
- auto using lt_1_length_limb_widths, length_carry_full, length_to_list
+ auto using B_pos, B_compat, lt_1_length_limb_widths, length_carry_full, length_to_list, ge_modulus_01
end.
rewrite !decode_mod_Fdecode by auto using length_carry_full, length_to_list.
cbv [carry_full].
@@ -941,7 +941,7 @@ Section CanonicalizationProofs.
rewrite from_list_to_list; reflexivity.
Qed.
- Lemma freeze_rep : forall u x, rep u x -> rep (freeze u) x.
+ Lemma freeze_rep : forall u x, rep u x -> rep (freeze B u) x.
Proof.
cbv [rep]; intros.
apply F.eq_to_Z_iff.
@@ -952,7 +952,7 @@ Section CanonicalizationProofs.
Lemma freeze_canonical : forall u v x y, rep u x -> rep v y ->
initial_bounds u ->
initial_bounds v ->
- (x = y <-> fieldwise Logic.eq (freeze u) (freeze v)).
+ (x = y <-> fieldwise Logic.eq (freeze B u) (freeze B v)).
Proof.
intros; apply bounded_canonical; auto using freeze_rep, minimal_rep_freeze.
Qed.
@@ -977,7 +977,7 @@ Section SquareRootProofs.
Lemma eqb_true_iff : forall u v x y,
bounded_by u freeze_input_bounds -> bounded_by v freeze_input_bounds ->
- u ~= x -> v ~= y -> (x = y <-> eqb u v = true).
+ u ~= x -> v ~= y -> (x = y <-> eqb B u v = true).
Proof.
cbv [eqb freeze_input_bounds]. intros.
rewrite fieldwiseb_fieldwise by (apply Z.eqb_eq).
@@ -986,10 +986,10 @@ Section SquareRootProofs.
Lemma eqb_false_iff : forall u v x y,
bounded_by u freeze_input_bounds -> bounded_by v freeze_input_bounds ->
- u ~= x -> v ~= y -> (x <> y <-> eqb u v = false).
+ u ~= x -> v ~= y -> (x <> y <-> eqb B u v = false).
Proof.
intros.
- case_eq (eqb u v).
+ case_eq (eqb B u v).
+ rewrite <-eqb_true_iff by eassumption; split; intros;
congruence || contradiction.
+ split; intros; auto.
@@ -1032,24 +1032,24 @@ Section SquareRootProofs.
Lemma sqrt_5mod8_correct : forall u x, u ~= x ->
bounded_by u pow_input_bounds -> bounded_by u freeze_input_bounds ->
- (sqrt_5mod8 mul_ pow_ chain chain_correct sqrt_m1 u) ~= F.sqrt_5mod8 (decode sqrt_m1) x.
+ (sqrt_5mod8 B mul_ pow_ chain chain_correct sqrt_m1 u) ~= F.sqrt_5mod8 (decode sqrt_m1) x.
Proof.
repeat match goal with
| |- _ => progress (cbv [sqrt_5mod8 F.sqrt_5mod8]; intros)
| |- _ => rewrite @F.pow_2_r in *
| |- _ => rewrite eqb_correct in * by eassumption
- | |- (if eqb ?a ?b then _ else _) ~=
+ | |- (if eqb _ ?a ?b then _ else _) ~=
(if dec (?c = _) then _ else _) =>
assert (a ~= c); rewrite !mul_equiv, pow_equiv in *;
repeat break_if
| |- _ => apply mul_rep; try reflexivity;
rewrite <-chain_correct; apply pow_rep; eassumption
| |- _ => rewrite <-chain_correct; apply pow_rep; eassumption
- | H : eqb ?a ?b = true |- _ =>
+ | H : eqb _ ?a ?b = true |- _ =>
rewrite <-(eqb_true_iff a b) in H
by (eassumption || rewrite <-mul_equiv, <-pow_equiv;
apply mul_bounded, pow_bounded; auto)
- | H : eqb ?a ?b = false |- _ =>
+ | H : eqb _ ?a ?b = false |- _ =>
rewrite <-(eqb_false_iff a b) in H
by (eassumption || rewrite <-mul_equiv, <-pow_equiv;
apply mul_bounded, pow_bounded; auto)
diff --git a/src/Specific/GF25519.v b/src/Specific/GF25519.v
index 36feb2f4c..e89615dde 100644
--- a/src/Specific/GF25519.v
+++ b/src/Specific/GF25519.v
@@ -129,7 +129,7 @@ Definition zero_subst : zero = zero_ := eq_refl zero_.
Definition modulus_digits_ := Eval compute in ModularBaseSystemList.modulus_digits.
Definition modulus_digits_subst : ModularBaseSystemList.modulus_digits = modulus_digits_ := eq_refl modulus_digits_.
-Local Opaque Z.shiftr Z.shiftl Z.land Z.mul Z.add Z.sub Z.lor Let_In Z.eqb Z.ltb Z.leb andb.
+Local Opaque Z.shiftr Z.shiftl Z.land Z.mul Z.add Z.sub Z.lor Let_In Z.eqb Z.ltb Z.leb ModularBaseSystemList.neg.
Definition app_7 {T} (f : wire_digits) (P : wire_digits -> T) : T.
Proof.
@@ -461,7 +461,7 @@ Proof.
Qed.
Definition ge_modulus_sig (f : fe25519) :
- { b : bool | b = ge_modulus_opt (to_list 10 f) }.
+ { b : Z | b = ge_modulus_opt (to_list 10 f) }.
Proof.
cbv [fe25519] in *.
repeat match goal with p : (_ * Z)%type |- _ => destruct p end.
@@ -471,7 +471,7 @@ Proof.
reflexivity.
Defined.
-Definition ge_modulus (f : fe25519) : bool :=
+Definition ge_modulus (f : fe25519) : Z :=
Eval cbv beta iota delta [proj1_sig ge_modulus_sig] in
let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
proj1_sig (ge_modulus_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)).
@@ -486,11 +486,11 @@ Proof.
Defined.
Definition freeze_sig (f : fe25519) :
- { f' : fe25519 | f' = from_list_default 0 10 (freeze_opt c_ (to_list 10 f)) }.
+ { f' : fe25519 | f' = from_list_default 0 10 (freeze_opt (int_width := int_width) c_ (to_list 10 f)) }.
Proof.
cbv [fe25519] in *.
repeat match goal with p : (_ * Z)%type |- _ => destruct p end.
- eexists; cbv [freeze_opt].
+ eexists; cbv [freeze_opt int_width].
cbv [to_list to_list'].
cbv [conditional_subtract_modulus_opt].
rewrite !modulus_digits_subst.
@@ -509,7 +509,7 @@ Definition freeze (f : fe25519) : fe25519 :=
proj1_sig (freeze_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)).
Definition freeze_correct (f : fe25519)
- : freeze f = from_list_default 0 10 (freeze_opt c_ (to_list 10 f)).
+ : freeze f = from_list_default 0 10 (freeze_opt (int_width := int_width) c_ (to_list 10 f)).
Proof.
pose proof (proj2_sig (freeze_sig f)).
cbv [fe25519] in *.
@@ -528,20 +528,28 @@ Proof.
Defined.
Definition fieldwiseb (f g : fe25519) : bool
- := Eval cbv beta iota delta [proj1_sig fieldwiseb_sig] in proj1_sig (fieldwiseb_sig f g).
-
-Definition fieldwiseb_correct (f g : fe25519)
- : fieldwiseb f g = @Tuple.fieldwiseb Z Z 10 Z.eqb f g
- := Eval cbv beta iota delta [proj2_sig fieldwiseb_sig] in proj2_sig (fieldwiseb_sig f g).
+ := Eval cbv beta iota delta [proj1_sig fieldwiseb_sig] in
+ let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
+ let '(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9) := g in
+ proj1_sig (fieldwiseb_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
+ (g0, g1, g2, g3, g4, g5, g6, g7, g8, g9)).
+
+Lemma fieldwiseb_correct (f g : fe25519)
+ : fieldwiseb f g = @Tuple.fieldwiseb Z Z 10 Z.eqb f g.
+Proof.
+ set (f' := f); set (g' := g).
+ hnf in f, g; destruct_head' prod.
+ exact (proj2_sig (fieldwiseb_sig f' g')).
+Qed.
Definition eqb_sig (f g : fe25519) :
- { b | b = eqb f g }.
+ { b | b = eqb int_width f g }.
Proof.
cbv [eqb].
cbv [fe25519] in *.
repeat match goal with p : (_ * Z)%type |- _ => destruct p end.
eexists.
- cbv [ModularBaseSystem.freeze].
+ cbv [ModularBaseSystem.freeze int_width].
rewrite <-!from_list_default_eq with (d := 0).
rewrite <-!(freeze_opt_correct c_) by auto using length_to_list.
rewrite <-!freeze_correct.
@@ -550,17 +558,26 @@ Proof.
Defined.
Definition eqb (f g : fe25519) : bool
- := Eval cbv beta iota delta [proj1_sig eqb_sig] in proj1_sig (eqb_sig f g).
-
-Definition eqb_correct (f g : fe25519)
- : eqb f g = ModularBaseSystem.eqb f g
- := Eval cbv beta iota delta [proj2_sig eqb_sig] in proj2_sig (eqb_sig f g).
+ := Eval cbv beta iota delta [proj1_sig eqb_sig] in
+ let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
+ let '(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9) := g in
+ proj1_sig (eqb_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
+ (g0, g1, g2, g3, g4, g5, g6, g7, g8, g9)).
+
+Lemma eqb_correct (f g : fe25519)
+ : eqb f g = ModularBaseSystem.eqb int_width f g.
+Proof.
+ set (f' := f); set (g' := g).
+ hnf in f, g; destruct_head' prod.
+ exact (proj2_sig (eqb_sig f' g')).
+Qed.
Definition sqrt_sig (f : fe25519) :
- { f' : fe25519 | f' = sqrt_5mod8_opt k_ c_ one_ sqrt_m1 f}.
+ { f' : fe25519 | f' = sqrt_5mod8_opt (int_width := int_width) k_ c_ one_ sqrt_m1 f}.
Proof.
eexists.
- cbv [sqrt_5mod8_opt].
+ cbv [sqrt_5mod8_opt int_width].
+ rewrite <- pow_correct.
apply Proper_Let_In_nd_changebody; [reflexivity|intro].
set_evars. rewrite <-!mul_correct, <-eqb_correct. subst_evars.
reflexivity.
@@ -662,4 +679,4 @@ Definition unpack (f : wire_digits) : fe25519 :=
Definition unpack_correct (f : wire_digits)
: unpack f = unpack_opt params25519 wire_widths_nonneg bits_eq f
- := Eval cbv beta iota delta [proj2_sig pack_sig] in proj2_sig (unpack_sig f).
+ := Eval cbv beta iota delta [proj2_sig pack_sig] in proj2_sig (unpack_sig f). \ No newline at end of file
diff --git a/src/Specific/GF25519Bounded.v b/src/Specific/GF25519Bounded.v
index e133e62ad..5d29d4cd5 100644
--- a/src/Specific/GF25519Bounded.v
+++ b/src/Specific/GF25519Bounded.v
@@ -16,6 +16,7 @@ Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.Notations.
+Require Import Crypto.Util.Bool.
Require Import Crypto.Util.Decidable.
Require Import Crypto.Algebra.
Import ListNotations.
@@ -33,25 +34,37 @@ Local Ltac define_unop f opW blem :=
refine (exist_fe25519W (opW (proj1_fe25519W f)) _);
abstract bounded_t opW blem.
-Definition addW (f g : fe25519W) : fe25519W := interp_bexpr radd f g.
-Definition subW (f g : fe25519W) : fe25519W := interp_bexpr rsub f g.
-Definition mulW (f g : fe25519W) : fe25519W := interp_bexpr rmul f g.
-Definition oppW (f : fe25519W) : fe25519W := interp_uexpr ropp f.
-Definition freezeW (f : fe25519W) : fe25519W := interp_uexpr rfreeze f.
+Local Opaque Let_In.
+Local Arguments interp_radd / _ _.
+Local Arguments interp_rsub / _ _.
+Local Arguments interp_rmul / _ _.
+Local Arguments interp_ropp / _.
+Local Arguments interp_rfreeze / _.
+Definition addW (f g : fe25519W) : fe25519W := Eval simpl in interp_radd f g.
+Definition subW (f g : fe25519W) : fe25519W := Eval simpl in interp_rsub f g.
+Definition mulW (f g : fe25519W) : fe25519W := Eval simpl in interp_rmul f g.
+Definition oppW (f : fe25519W) : fe25519W := Eval simpl in interp_ropp f.
+Definition freezeW (f : fe25519W) : fe25519W := Eval simpl in interp_rfreeze f.
+Local Transparent Let_In.
Definition powW (f : fe25519W) chain := fold_chain_opt (proj1_fe25519W one) mulW chain [f].
Definition invW (f : fe25519W) : fe25519W
:= Eval cbv -[Let_In fe25519W mulW] in powW f (chain inv_ec).
-Definition add (f g : fe25519) : fe25519.
-Proof. define_binop f g addW radd_correct_and_bounded. Defined.
-Definition sub (f g : fe25519) : fe25519.
-Proof. define_binop f g subW rsub_correct_and_bounded. Defined.
-Definition mul (f g : fe25519) : fe25519.
-Proof. define_binop f g mulW rmul_correct_and_bounded. Defined.
-Definition opp (f : fe25519) : fe25519.
-Proof. define_unop f oppW ropp_correct_and_bounded. Defined.
-Definition freeze (f : fe25519) : fe25519.
-Proof. define_unop f freezeW rfreeze_correct_and_bounded. Defined.
+Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
+ change opW with (interp_rop);
+ rewrite pre_rewrite;
+ intros; apply rop_cb; assumption.
+
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
+Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
+Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
+Lemma freezeW_correct_and_bounded : iunop_correct_and_bounded freezeW freeze.
+Proof. port_correct_and_bounded interp_rfreeze_correct freezeW interp_rfreeze rfreeze_correct_and_bounded. Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
Proof.
@@ -62,7 +75,7 @@ Proof.
{ intros; progress rewrite <- ?mul_correct,
<- ?(fun X Y => proj1 (rmul_correct_and_bounded _ _ X Y)) by assumption.
apply rmul_correct_and_bounded; assumption. }
- { intros; symmetry; apply rmul_correct_and_bounded; assumption. }
+ { intros; change mulW with interp_rmul; rewrite interp_rmul_correct; symmetry; apply rmul_correct_and_bounded; assumption. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -79,34 +92,169 @@ Proof.
apply powW_correct_and_bounded.
Qed.
+Definition fieldwisebW_sig (f g : fe25519W)
+ : { b | b = GF25519.fieldwiseb (fe25519WToZ f) (fe25519WToZ g) }.
+Proof.
+ hnf in f, g; destruct_head' prod.
+ eexists.
+ cbv [GF25519.fieldwiseb fe25519WToZ].
+ rewrite !word64eqb_Zeqb.
+ reflexivity.
+Defined.
+
+Definition fieldwisebW (f g : fe25519W) : bool :=
+ Eval cbv beta iota delta [proj1_sig fieldwisebW_sig] in
+ let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
+ let '(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9) := g in
+ proj1_sig (fieldwisebW_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
+ (g0, g1, g2, g3, g4, g5, g6, g7, g8, g9)).
+
+Lemma fieldwisebW_correct f g
+ : fieldwisebW f g = GF25519.fieldwiseb (fe25519WToZ f) (fe25519WToZ g).
+Proof.
+ set (f' := f); set (g' := g).
+ hnf in f, g; destruct_head' prod.
+ exact (proj2_sig (fieldwisebW_sig f' g')).
+Qed.
+
+Local Arguments freezeW : simpl never.
+
+Definition eqbW_sig (f g : fe25519W)
+ : { b | is_bounded (fe25519WToZ f) = true
+ -> is_bounded (fe25519WToZ g) = true
+ -> b = GF25519.eqb (fe25519WToZ f) (fe25519WToZ g) }.
+Proof.
+ pose proof (fun pf => proj1 (freezeW_correct_and_bounded f pf)) as frf.
+ pose proof (fun pf => proj1 (freezeW_correct_and_bounded g pf)) as frg.
+ hnf in f, g; destruct_head' prod.
+ eexists.
+ unfold GF25519.eqb.
+ simpl @fe25519WToZ in *; cbv beta iota.
+ intros.
+ rewrite <- frf, <- frg by assumption.
+ rewrite <- fieldwisebW_correct.
+ reflexivity.
+Defined.
+
+Definition eqbW (f g : fe25519W) : bool :=
+ Eval cbv beta iota delta [proj1_sig eqbW_sig] in
+ let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
+ let '(g0, g1, g2, g3, g4, g5, g6, g7, g8, g9) := g in
+ proj1_sig (eqbW_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
+ (g0, g1, g2, g3, g4, g5, g6, g7, g8, g9)).
+
+Lemma eqbW_correct f g
+ : is_bounded (fe25519WToZ f) = true
+ -> is_bounded (fe25519WToZ g) = true
+ -> eqbW f g = GF25519.eqb (fe25519WToZ f) (fe25519WToZ g).
+Proof.
+ set (f' := f); set (g' := g).
+ hnf in f, g; destruct_head' prod.
+ exact (proj2_sig (eqbW_sig f' g')).
+Qed.
+
+Definition sqrt_m1W : fe25519W :=
+ Eval vm_compute in fe25519ZToW sqrt_m1.
+
+Definition sqrtW_sig
+ : { sqrtW | iunop_correct_and_bounded sqrtW GF25519.sqrt }.
+Proof.
+ eexists.
+ unfold GF25519.sqrt.
+ intros; rewrite <- (fun pf => proj1 (powW_correct_and_bounded _ _ pf)) by assumption.
+ match goal with
+ | [ |- context G[dlet x := fe25519WToZ ?v in @?f x] ]
+ => let G' := context G[dlet x := v in f (fe25519WToZ x)] in
+ cut G'; cbv beta;
+ [ cbv [Let_In]; exact (fun x => x) | ]
+ end.
+ split.
+ { etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody_eq; intros.
+ set_evars.
+ change sqrt_m1 with (fe25519WToZ sqrt_m1W).
+ rewrite <- !(fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)), <- eqbW_correct, (pull_bool_if fe25519WToZ)
+ by repeat match goal with
+ | _ => progress subst
+ | [ |- is_bounded (fe25519WToZ ?op) = true ]
+ => lazymatch op with
+ | mulW _ _ => apply mulW_correct_and_bounded
+ | powW _ _ => apply powW_correct_and_bounded
+ | sqrt_m1W => vm_compute; reflexivity
+ | _ => assumption
+ end
+ end.
+ subst_evars; reflexivity.
+ } Unfocus.
+ lazymatch goal with
+ | [ |- context G[dlet x := ?v in fe25519WToZ (@?f x)] ]
+ => let G' := context G[fe25519WToZ (dlet x := v in f x)] in
+ cut G'; cbv beta;
+ [ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
+ end.
+ reflexivity. }
+ { cbv [Let_In].
+ break_if.
+ { apply powW_correct_and_bounded; assumption. }
+ { apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ].
+ apply powW_correct_and_bounded; assumption. } }
+Defined.
+
+Definition sqrtW (f : fe25519W) : fe25519W :=
+ Eval cbv beta iota delta [proj1_sig sqrtW_sig] in
+ let '(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9) := f in
+ proj1_sig sqrtW_sig (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9).
+
+Lemma sqrtW_correct_and_bounded : iunop_correct_and_bounded sqrtW GF25519.sqrt.
+Proof.
+ intro f.
+ set (f' := f).
+ hnf in f; destruct_head' prod.
+ assert (H : sqrtW f' = proj1_sig sqrtW_sig f')
+ by (subst f'; cbv beta iota delta [proj1_sig sqrtW_sig sqrtW]; reflexivity).
+ rewrite H.
+ exact (proj2_sig sqrtW_sig f').
+Qed.
+
+Definition add (f g : fe25519) : fe25519.
+Proof. define_binop f g addW addW_correct_and_bounded. Defined.
+Definition sub (f g : fe25519) : fe25519.
+Proof. define_binop f g subW subW_correct_and_bounded. Defined.
+Definition mul (f g : fe25519) : fe25519.
+Proof. define_binop f g mulW mulW_correct_and_bounded. Defined.
+Definition opp (f : fe25519) : fe25519.
+Proof. define_unop f oppW oppW_correct_and_bounded. Defined.
+Definition freeze (f : fe25519) : fe25519.
+Proof. define_unop f freezeW freezeW_correct_and_bounded. Defined.
+
Definition pow (f : fe25519) (chain : list (nat * nat)) : fe25519.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe25519) : fe25519.
Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Definition sqrt (f : fe25519) : fe25519.
+Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
-Local Ltac unop_correct_t op opW rop_correct_and_bounded :=
- cbv [op opW]; rewrite proj1_fe25519_exist_fe25519W;
- rewrite (fun X => proj1 (rop_correct_and_bounded _ X)) by apply is_bounded_proj1_fe25519;
- try reflexivity.
-Local Ltac binop_correct_t op opW rop_correct_and_bounded :=
- cbv [op opW]; rewrite proj1_fe25519_exist_fe25519W;
- rewrite (fun X Y => proj1 (rop_correct_and_bounded _ _ X Y)) by apply is_bounded_proj1_fe25519;
- try reflexivity.
+Local Ltac op_correct_t op opW_correct_and_bounded :=
+ cbv [op]; rewrite proj1_fe25519_exist_fe25519W;
+ apply opW_correct_and_bounded; apply is_bounded_proj1_fe25519.
Lemma add_correct (f g : fe25519) : proj1_fe25519 (add f g) = carry_add (proj1_fe25519 f) (proj1_fe25519 g).
-Proof. binop_correct_t add addW radd_correct_and_bounded. Qed.
+Proof. op_correct_t add addW_correct_and_bounded. Qed.
Lemma sub_correct (f g : fe25519) : proj1_fe25519 (sub f g) = carry_sub (proj1_fe25519 f) (proj1_fe25519 g).
-Proof. binop_correct_t sub subW rsub_correct_and_bounded. Qed.
+Proof. op_correct_t sub subW_correct_and_bounded. Qed.
Lemma mul_correct (f g : fe25519) : proj1_fe25519 (mul f g) = GF25519.mul (proj1_fe25519 f) (proj1_fe25519 g).
-Proof. binop_correct_t mul mulW rmul_correct_and_bounded. Qed.
+Proof. op_correct_t mul mulW_correct_and_bounded. Qed.
Lemma opp_correct (f : fe25519) : proj1_fe25519 (opp f) = carry_opp (proj1_fe25519 f).
-Proof. unop_correct_t opp oppW ropp_correct_and_bounded. Qed.
+Proof. op_correct_t opp oppW_correct_and_bounded. Qed.
Lemma freeze_correct (f : fe25519) : proj1_fe25519 (freeze f) = GF25519.freeze (proj1_fe25519 f).
-Proof. unop_correct_t freeze freezeW rfreeze_correct_and_bounded. Qed.
+Proof. op_correct_t freeze freezeW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe25519) chain : proj1_fe25519 (pow f chain) = GF25519.pow (proj1_fe25519 f) chain.
-Proof. unop_correct_t pow pow (powW_correct_and_bounded chain). Qed.
+Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe25519) : proj1_fe25519 (inv f) = GF25519.inv (proj1_fe25519 f).
-Proof. unop_correct_t inv inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Lemma sqrt_correct (f : fe25519) : proj1_fe25519 (sqrt f) = GF25519.sqrt (proj1_fe25519 f).
+Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
Import Morphisms.
@@ -144,4 +292,4 @@ Proof.
{ reflexivity. }
Qed.
-(** TODO: pack, unpack, sqrt *)
+(** TODO: pack, unpack *)
diff --git a/src/Specific/GF25519BoundedCommon.v b/src/Specific/GF25519BoundedCommon.v
index 6e2213ee7..e044aa170 100644
--- a/src/Specific/GF25519BoundedCommon.v
+++ b/src/Specific/GF25519BoundedCommon.v
@@ -25,6 +25,10 @@ Definition word64 := Word.word 64.
Coercion word64ToZ (x : word64) : Z
:= Z.of_N (wordToN x).
Coercion ZToWord64 (x : Z) : word64 := NToWord _ (Z.to_N x).
+Definition w64eqb (x y : word64) := weqb x y.
+
+Lemma word64eqb_Zeqb x y : (word64ToZ x =? word64ToZ y)%Z = w64eqb x y.
+Proof. apply wordeqb_Zeqb. Qed.
(* END aliases for word extraction *)
@@ -39,8 +43,22 @@ Qed.
(* BEGIN precomputation. *)
Local Notation b_of exp := (0, 2^exp + 2^(exp-3))%Z (only parsing). (* max is [(0, 2^(exp+2) + 2^exp + 2^(exp-1) + 2^(exp-3) + 2^(exp-4) + 2^(exp-5) + 2^(exp-6) + 2^(exp-10) + 2^(exp-12) + 2^(exp-13) + 2^(exp-14) + 2^(exp-15) + 2^(exp-17) + 2^(exp-23) + 2^(exp-24))%Z] *)
-Local Notation Z_of exp := { v : Z | fst (b_of exp) <= v <= snd (b_of exp) }.
-Local Notation word_of exp := { v : word64 | fst (b_of exp) <= v <= snd (b_of exp) }.
+Record bounded_word (lower upper : Z) :=
+ Build_bounded_word'
+ { proj_word :> word64;
+ word_bounded : andb (lower <=? proj_word)%Z (proj_word <=? upper)%Z = true }.
+Arguments proj_word {_ _} _.
+Arguments word_bounded {_ _} _.
+Arguments Build_bounded_word' {_ _} _ _.
+Definition Build_bounded_word {lower upper} (proj_word : word64) (word_bounded : andb (lower <=? proj_word)%Z (proj_word <=? upper)%Z = true)
+ : bounded_word lower upper
+ := Build_bounded_word'
+ proj_word
+ (match andb (lower <=? proj_word)%Z (proj_word <=? upper)%Z as b return b = true -> b = true with
+ | true => fun _ => eq_refl
+ | false => fun x => x
+ end word_bounded).
+Local Notation word_of exp := (bounded_word (fst (b_of exp)) (snd (b_of exp))).
Definition bounds : list (Z * Z)
:= Eval compute in
[b_of 25; b_of 26; b_of 25; b_of 26; b_of 25; b_of 26; b_of 25; b_of 26; b_of 25; b_of 26].
@@ -58,8 +76,8 @@ Definition fe25519 :=
(word_of 25 * word_of 26 * word_of 25 * word_of 26 * word_of 25 * word_of 26 * word_of 25 * word_of 26 * word_of 25 * word_of 26)%type.
Definition proj1_fe25519W (x : fe25519) : fe25519W
:= let '(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) := x in
- (proj1_sig x0, proj1_sig x1, proj1_sig x2, proj1_sig x3, proj1_sig x4,
- proj1_sig x5, proj1_sig x6, proj1_sig x7, proj1_sig x8, proj1_sig x9).
+ (proj_word x0, proj_word x1, proj_word x2, proj_word x3, proj_word x4,
+ proj_word x5, proj_word x6, proj_word x7, proj_word x8, proj_word x9).
Coercion proj1_fe25519 (x : fe25519) : Specific.GF25519.fe25519
:= fe25519WToZ (proj1_fe25519W x).
Definition is_bounded (x : Specific.GF25519.fe25519) : bool
@@ -72,40 +90,22 @@ Definition is_bounded (x : Specific.GF25519.fe25519) : bool
Lemma is_bounded_proj1_fe25519 (x : fe25519) : is_bounded (proj1_fe25519 x) = true.
Proof.
- refine (let '(exist x0 p0, exist x1 p1, exist x2 p2, exist x3 p3, exist x4 p4,
- exist x5 p5, exist x6 p6, exist x7 p7, exist x8 p8, exist x9 p9)
+ refine (let '(Build_bounded_word' x0 p0, Build_bounded_word' x1 p1, Build_bounded_word' x2 p2, Build_bounded_word' x3 p3, Build_bounded_word' x4 p4,
+ Build_bounded_word' x5 p5, Build_bounded_word' x6 p6, Build_bounded_word' x7 p7, Build_bounded_word' x8 p8, Build_bounded_word' x9 p9)
as x := x return is_bounded (proj1_fe25519 x) = true in
_).
- cbv [is_bounded proj1_fe25519 proj1_fe25519W fe25519WToZ to_list length bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map List.rev List.app proj1_sig].
+ cbv [is_bounded proj1_fe25519 proj1_fe25519W fe25519WToZ to_list length bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map List.rev List.app proj_word].
apply fold_right_andb_true_iff_fold_right_and_True.
cbv [fold_right List.map].
cbv beta in *.
- repeat split; rewrite !Bool.andb_true_iff, !Z.leb_le;
- assumption.
+ repeat split; assumption.
Qed.
-(* Make small [vm_computable] versions of proofs *)
-Definition correct_le_le {l v u} : l <= v <= u -> l <= v <= u.
-Proof.
- intro pf; pose proof (proj1 pf) as pf1; pose proof (proj2 pf) as pf2; clear pf;
- split; hnf in *;
- lazymatch goal with
- | [ H : ?x = Gt -> False |- ?x = Gt -> False ]
- => revert H;
- refine match x as y return (y = Gt -> False) -> y = Gt -> False with
- | Gt => fun f => f
- | _ => fun _ pf => match pf with
- | eq_refl => I
- end
- end
- end.
-Defined.
-
(** TODO: Turn this into a lemma to speed up proofs *)
Ltac unfold_is_bounded_in H :=
unfold is_bounded, fe25519WToZ in H;
cbv [to_list length bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app] in H;
- rewrite !Bool.andb_true_iff, !Z.leb_le in H.
+ rewrite !Bool.andb_true_iff in H.
Definition Pow2_64 := Eval compute in 2^64.
Definition unfold_Pow2_64 : 2^64 = Pow2_64 := eq_refl.
@@ -113,8 +113,8 @@ Definition unfold_Pow2_64 : 2^64 = Pow2_64 := eq_refl.
Definition exist_fe25519W (x : fe25519W) : is_bounded (fe25519WToZ x) = true -> fe25519.
Proof.
refine (let '(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) as x := x return is_bounded (fe25519WToZ x) = true -> fe25519 in
- fun H => (fun H' => (exist _ x0 _, exist _ x1 _, exist _ x2 _, exist _ x3 _, exist _ x4 _,
- exist _ x5 _, exist _ x6 _, exist _ x7 _, exist _ x8 _, exist _ x9 _))
+ fun H => (fun H' => (Build_bounded_word x0 _, Build_bounded_word x1 _, Build_bounded_word x2 _, Build_bounded_word x3 _, Build_bounded_word x4 _,
+ Build_bounded_word x5 _, Build_bounded_word x6 _, Build_bounded_word x7 _, Build_bounded_word x8 _, Build_bounded_word x9 _))
(let H' := proj1 (@fold_right_andb_true_iff_fold_right_and_True _) H in
_));
[
@@ -122,7 +122,8 @@ Proof.
| clearbody H'; clear H x;
unfold_is_bounded_in H';
exact H' ];
- destruct_head and; auto.
+ destruct_head and; auto;
+ rewrite_hyp !*; reflexivity.
Defined.
Definition exist_fe25519' (x : Specific.GF25519.fe25519) : is_bounded x = true -> fe25519.
@@ -133,6 +134,7 @@ Proof.
pose proof H as H';
unfold_is_bounded_in H;
destruct_head and;
+ Z.ltb_to_lt;
rewrite !ZToWord64ToZ by (simpl; omega);
assumption
).
@@ -144,11 +146,11 @@ Proof.
fun H => _).
let v := constr:(exist_fe25519' (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) H) in
let rec do_refine v :=
- first [ let v' := (eval cbv [exist_fe25519W fe25519ZToW exist_fe25519' proj1_sig snd fst] in (proj1_sig v)) in
- refine (exist _ v' (correct_le_le _)); abstract exact (proj2_sig v)
- | let v' := (eval cbv [exist_fe25519W fe25519ZToW exist_fe25519' proj1_sig snd fst] in (proj1_sig (snd v))) in
- refine (_, exist _ v' (correct_le_le _));
- [ do_refine (fst v) | abstract exact (proj2_sig (snd v)) ] ] in
+ first [ let v' := (eval cbv [exist_fe25519W fe25519ZToW exist_fe25519' proj_word Build_bounded_word snd fst] in (proj_word v)) in
+ refine (Build_bounded_word v' _); abstract exact (word_bounded v)
+ | let v' := (eval cbv [exist_fe25519W fe25519ZToW exist_fe25519' proj_word Build_bounded_word snd fst] in (proj_word (snd v))) in
+ refine (_, Build_bounded_word v' _);
+ [ do_refine (fst v) | abstract exact (word_bounded (snd v)) ] ] in
do_refine v.
Defined.
@@ -171,9 +173,10 @@ Proof.
revert pf.
refine (let '(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) as x := x return forall pf : is_bounded x = true, proj1_fe25519 (exist_fe25519 x pf) = x in
fun pf => _).
- cbv [proj1_fe25519 exist_fe25519 proj1_fe25519W fe25519WToZ proj1_sig].
+ cbv [proj1_fe25519 exist_fe25519 proj1_fe25519W fe25519WToZ proj_word Build_bounded_word].
unfold_is_bounded_in pf.
destruct_head and.
+ Z.ltb_to_lt.
rewrite !ZToWord64ToZ by (rewrite unfold_Pow2_64; cbv [Pow2_64]; omega).
reflexivity.
Qed.
@@ -182,9 +185,9 @@ Qed.
(* Precompute constants *)
-Definition one := Eval cbv -[Z.le] in exist_fe25519 Specific.GF25519.one_ eq_refl.
+Definition one := Eval vm_compute in exist_fe25519 Specific.GF25519.one_ eq_refl.
-Definition zero := Eval cbv -[Z.le] in exist_fe25519 Specific.GF25519.zero_ eq_refl.
+Definition zero := Eval vm_compute in exist_fe25519 Specific.GF25519.zero_ eq_refl.
Lemma fold_chain_opt_gen {A B} (F : A -> B) is_bounded ls id' op' id op chain
(Hid_bounded : is_bounded (F id') = true)
@@ -233,7 +236,7 @@ Proof.
cbv [Z.pow_pos Z.mul Pos.mul Pos.iter nth_default nth_error value] in *.
unfold is_bounded.
apply fold_right_andb_true_iff_fold_right_and_True.
- cbv [is_bounded proj1_fe25519 to_list length bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map List.rev List.app proj1_sig fold_right].
+ cbv [is_bounded proj1_fe25519 to_list length bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map List.rev List.app proj_word fold_right].
repeat split; rewrite !Bool.andb_true_iff, !Z.leb_le; omega.
Qed.
diff --git a/src/Util/Bool.v b/src/Util/Bool.v
index 5293268df..7b94c503e 100644
--- a/src/Util/Bool.v
+++ b/src/Util/Bool.v
@@ -41,3 +41,13 @@ Hint Rewrite Bool.orb_andb_distrib_r Bool.orb_andb_distrib_l : push_orb.
Hint Rewrite <- Bool.andb_orb_distrib_r Bool.andb_orb_distrib_l : push_orb.
Hint Rewrite <- Bool.orb_andb_distrib_r Bool.orb_andb_distrib_l : pull_orb.
Hint Rewrite Bool.andb_orb_distrib_r Bool.andb_orb_distrib_l : pull_orb.
+
+Definition pull_bool_if_dep {A B} (f : forall b : bool, A b -> B b) (b : bool) (x : A true) (y : A false)
+ : (if b return B b then f _ x else f _ y) = f b (if b return A b then x else y)
+ := if b return ((if b return B b then f _ x else f _ y) = f b (if b return A b then x else y))
+ then eq_refl
+ else eq_refl.
+
+Definition pull_bool_if {A B} (f : A -> B) (b : bool) (x : A) (y : A)
+ : (if b then f x else f y) = f (if b then x else y)
+ := @pull_bool_if_dep (fun _ => A) (fun _ => B) (fun _ => f) b x y.
diff --git a/src/Util/LetIn.v b/src/Util/LetIn.v
index db09baf9c..12e1e6d43 100644
--- a/src/Util/LetIn.v
+++ b/src/Util/LetIn.v
@@ -20,6 +20,10 @@ Global Instance Proper_Let_In_nd_changevalue {A B} (RA:relation A) {RB:relation
: Proper (RA ==> (RA ==> RB) ==> RB) (Let_In (P:=fun _=>B)).
Proof. cbv; intuition. Qed.
+Lemma Proper_Let_In_nd_changebody_eq {A P R} {Reflexive_R:@Reflexive P R} {x}
+ : Proper ((fun f g => forall a, x = a -> R (f a) (g a)) ==> R) (@Let_In A (fun _ => P) x).
+Proof. lazy; intros; subst; auto; congruence. Qed.
+
Definition app_Let_In_nd {A B T} (f:B->T) (e:A) (C:A->B)
: f (Let_In e C) = Let_In e (fun v => f (C v)) := eq_refl.
diff --git a/src/Util/WordUtil.v b/src/Util/WordUtil.v
index a89d02364..f2ceb047f 100644
--- a/src/Util/WordUtil.v
+++ b/src/Util/WordUtil.v
@@ -140,4 +140,21 @@ Lemma wordToNat_split1 : forall a b w, wordToNat (split1 a b w) = (wordToNat w)
Admitted.
Lemma wordToNat_wfirstn : forall a b w H, wordToNat (@wfirstn a b w H) = (wordToNat w) mod (2^a).
-Admitted. \ No newline at end of file
+Admitted.
+
+Lemma wordeqb_Zeqb {sz} (x y : word sz) : (Z.of_N (wordToN x) =? Z.of_N (wordToN y))%Z = weqb x y.
+Proof.
+ match goal with |- ?LHS = ?RHS => destruct LHS eqn:HL, RHS eqn:HR end;
+ repeat match goal with
+ | _ => reflexivity
+ | _ => progress unfold not in *
+ | [ H : Z.eqb _ _ = true |- _ ] => apply Z.eqb_eq in H
+ | [ |- Z.eqb _ _ = true ] => apply Z.eqb_eq
+ | [ H : context[Z.of_N _ = Z.of_N _] |- _ ] => rewrite N2Z.inj_iff in H
+ | [ H : wordToN _ = wordToN _ |- _ ] => apply wordToN_inj in H
+ | [ H : x = y :> word _ |- _ ] => apply weqb_true_iff in H
+ | [ H : ?x = false |- _ ] => progress rewrite <- H; clear H
+ | _ => congruence
+ | [ H : weqb _ _ = true |- _ ] => apply weqb_true_iff in H; subst
+ end.
+Qed.