diff options
Diffstat (limited to 'src/Curves/PointFormats.v')
-rw-r--r-- | src/Curves/PointFormats.v | 261 |
1 files changed, 195 insertions, 66 deletions
diff --git a/src/Curves/PointFormats.v b/src/Curves/PointFormats.v index 1e8df9337..32e6acdd0 100644 --- a/src/Curves/PointFormats.v +++ b/src/Curves/PointFormats.v @@ -1,18 +1,15 @@ -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory Crypto.Galois.ComputationalGaloisField. +Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory Crypto.Galois.ZGaloisField. Require Import Tactics.VerdiTactics. Require Import Logic.Eqdep_dec. Require Import BinNums NArith. -Module GaloisDefs (M : Modulus). - Module Export GT := GaloisTheory M. -End GaloisDefs. - Module Type TwistedEdwardsParams (M : Modulus). - Module Export GFDefs := GaloisDefs M. + Module Export GFDefs := ZGaloisField M. Local Open Scope GF_scope. + Axiom char_gt_2 : inject 2 <> 0. Parameter a : GF. Axiom a_nonzero : a <> 0. - Axiom a_square : exists x, x * x = a. + Axiom a_square : exists sqrt_a, sqrt_a^2 = a. Parameter d : GF. Axiom d_nonsquare : forall x, x * x <> d. End TwistedEdwardsParams. @@ -116,6 +113,129 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam Definition point := { P | onCurve P}. Definition mkPoint := exist onCurve. + Lemma GFdecidable_neq : forall x y : GF, Zbool.Zeq_bool x y = false -> x <> y. + Proof. + intros. intro. rewrite GFcomplete in H; intuition. + Qed. + + Ltac case_eq_GF a b := + case_eq (Zbool.Zeq_bool a b); intro Hx; + match type of Hx with + | Zbool.Zeq_bool (GFToZ a) (GFToZ b) = true => + pose proof (GFdecidable a b Hx) + | Zbool.Zeq_bool (GFToZ a) (GFToZ b) = false => + pose proof (GFdecidable_neq a b Hx) + end; clear Hx. + + Ltac rewriteAny := match goal with [H: _ = _ |- _ ] => rewrite H end. + Ltac rewriteLeftAny := match goal with [H: _ = _ |- _ ] => rewrite <- H end. + + (* https://eprint.iacr.org/2007/286.pdf Theorem 3.3 *) + (* c=1 and an extra a in front of x^2 *) + + Lemma root_zero : forall x p, x^p = 0 -> x = 0. + Admitted. + Lemma root_nonzero : forall x p, x^p <> 0 -> x <> 0. + Admitted. + Lemma mul_nonzero_l : forall a b, a*b <> 0 -> a <> 0. + Admitted. + Lemma mul_nonzero_r : forall a b, a*b <> 0 -> b <> 0. + Admitted. + Lemma mul_nonzero_nonzero : forall a b, a <> 0 -> b <> 0 -> a*b <> 0. + Admitted. + Lemma mul_zero_why : forall a b, a*b = 0 -> a = 0 \/ b = 0. + Admitted. + Definition GF_eq_dec : forall x y : GF, {x = y} + {x <> y}. + Admitted. + Hint Resolve mul_nonzero_nonzero. + + Ltac whatsNotZero := + repeat match goal with + | [H: ?lhs = ?rhs |- _ ] => + match goal with [Ha: lhs <> 0 |- _ ] => fail 1 | _ => idtac end; + assert (lhs <> 0) by (rewrite H; auto) + | [H: ?lhs = ?rhs |- _ ] => + match goal with [Ha: rhs <> 0 |- _ ] => fail 1 | _ => idtac end; + assert (rhs <> 0) by (rewrite H; auto) + | [H: (?a^?p)%GF <> 0 |- _ ] => + match goal with [Ha: a <> 0 |- _ ] => fail 1 | _ => idtac end; + assert (a <> 0) by (eapply root_nonzero; eauto) + | [H: (?a*?b)%GF <> 0 |- _ ] => + match goal with [Ha: a <> 0 |- _ ] => fail 1 | _ => idtac end; + assert (a <> 0) by (eapply mul_nonzero_l; eauto) + | [H: (?a*?b)%GF <> 0 |- _ ] => + match goal with [Ha: b <> 0 |- _ ] => fail 1 | _ => idtac end; + assert (b <> 0) by (eapply mul_nonzero_r; eauto) + end. + + Lemma edwardsAddComplete' x1 y1 x2 y2 : + onCurve (x1,y1) -> + onCurve (x2, y2) -> + (d*x1*x2*y1*y2)^2 <> 1. + Proof. + unfold onCurve; intuition; whatsNotZero. + + pose proof char_gt_2. pose proof a_nonzero as Ha_nonzero. + destruct a_square as [sqrt_a a_square]. + rewrite <- a_square in *. + + (* Furthermore... *) + pose proof (eq_refl (d*x1^2*y1^2*(sqrt_a^2*x2^2 + y2^2))) as Heqt. + rewrite H0 in Heqt at 2. + replace (d * x1 ^ 2 * y1 ^ 2 * (1 + d * x2 ^ 2 * y2 ^ 2)) + with (d*x1^2*y1^2 + (d*x1*x2*y1*y2)^2) in Heqt by field. + rewrite H1 in Heqt. + replace (d * x1 ^ 2 * y1 ^ 2 + 1) with (1 + d * x1 ^ 2 * y1 ^ 2) in Heqt by field. + rewrite <-H in Heqt. + + (* main equation for both potentially nonzero denominators *) + case_eq_GF (sqrt_a*x2 + y2) 0; case_eq_GF (sqrt_a*x2 - y2) 0; + try match goal with [H: ?f (sqrt_a * x2) y2 <> 0 |- _ ] => + assert ((f (sqrt_a*x1) (d * x1 * x2 * y1 * y2*y1))^2 = + f ((sqrt_a^2)*x1^2 + (d * x1 * x2 * y1 * y2)^2*y1^2) + (d * x1 * x2 * y1 * y2*sqrt_a*(inject 2)*x1*y1)) as Heqw1 by field; + rewrite H1 in *; + replace (1 * y1^2) with (y1^2) in * by field; + rewrite <- Heqt in *; + assert (d = (f (sqrt_a * x1) (d * x1 * x2 * y1 * y2 * y1))^2 / + (x1 * y1 * (f (sqrt_a * x2) y2))^2) + by (rewriteAny; field; auto); + match goal with [H: d = (?n^2)/(?l^2) |- _ ] => + destruct (d_nonsquare (n/l)); (remember n; rewriteAny; field; auto) + end + end. + + assert (Hc: (sqrt_a * x2 + y2) + (sqrt_a * x2 - y2) = 0) by (repeat rewriteAny; field). + replace (sqrt_a * x2 + y2 + (sqrt_a * x2 - y2)) with (inject 2 * sqrt_a * x2) in Hc by field. + + (* contradiction: product of nonzero things is zero *) + destruct (mul_zero_why _ _ Hc) as [Hcc|Hcc]; try solve [subst; intuition]; + destruct (mul_zero_why _ _ Hcc) as [Hccc|Hccc]; subst; intuition; apply Ha_nonzero; field. + Qed. + + Lemma edwardsAddCompletePlus x1 y1 x2 y2 : + onCurve (x1,y1) -> + onCurve (x2, y2) -> + (1 + d*x1*x2*y1*y2) <> 0. + Proof. + unfold onCurve; intros; case_eq_GF (d*x1*x2*y1*y2) (0-1)%GF. + - assert ((d*x1*x2*y1*y2)^2 = 1) by (rewriteAny; field). destruct (edwardsAddComplete' x1 y1 x2 y2); auto. + - replace (d * x1 * x2 * y1 * y2) with (1+d * x1 * x2 * y1 * y2-1) in H1 by field. + intro; rewrite H2 in H1; intuition. + Qed. + + Lemma edwardsAddCompletePlusMinus x1 y1 x2 y2 : + onCurve (x1,y1) -> + onCurve (x2, y2) -> + (1 - d*x1*x2*y1*y2) <> 0. + Proof. + unfold onCurve; intros; case_eq_GF (d*x1*x2*y1*y2) (1)%GF. + - assert ((d*x1*x2*y1*y2)^2 = 1) by (rewriteAny; field). destruct (edwardsAddComplete' x1 y1 x2 y2); auto. + - replace (d * x1 * x2 * y1 * y2) with ((1-(1-d * x1 * x2 * y1 * y2))) in H1 by field. + intro; rewrite H2 in H1; apply H1; field. + Qed. + Hint Resolve edwardsAddCompletePlus edwardsAddCompletePlusMinus. + Definition projX (P:point) := fst (proj1_sig P). Definition projY (P:point) := snd (proj1_sig P). @@ -125,7 +245,7 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam Hint Unfold onCurve mkPoint. Definition zero : point. exists (0, 1). - abstract (unfold onCurve; ring). + abstract (unfold onCurve; field). Defined. Definition unifiedAdd' (P1' P2' : (GF*GF)) := @@ -133,14 +253,55 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam let '(x2, y2) := P2' in (((x1*y2 + y1*x2)/(1 + d*x1*x2*y1*y2)) , ((y1*y2 - a*x1*x2)/(1 - d*x1*x2*y1*y2))). - Definition unifiedAdd (P1 P2 : point) : point. refine ( + Lemma unifiedAdd'_onCurve x1 y1 x2 y2 x3 y3 + (H: (x3, y3) = unifiedAdd' (x1, y1) (x2, y2)) : + onCurve (x1,y1) -> onCurve (x2, y2) -> onCurve (x3, y3). + Proof. + (* https://eprint.iacr.org/2007/286.pdf Theorem 3.1; + * c=1 and an extra a in front of x^2 *) + unfold unifiedAdd', onCurve in *; injection H; clear H; intros. + + Ltac t x1 y1 x2 y2 := + assert ((a*x2^2 + y2^2)*d*x1^2*y1^2 + = (1 + d*x2^2*y2^2) * d*x1^2*y1^2) by (rewriteAny; auto); + assert (a*x1^2 + y1^2 - (a*x2^2 + y2^2)*d*x1^2*y1^2 + = 1 - d^2*x1^2*x2^2*y1^2*y2^2) by (repeat rewriteAny; field). + t x1 y1 x2 y2; t x2 y2 x1 y1. + + remember ((a*x1^2 + y1^2 - (a*x2^2+y2^2)*d*x1^2*y1^2)*(a*x2^2 + y2^2 - + (a*x1^2 + y1^2)*d*x2^2*y2^2)) as T. + assert (HT1: T = (1 - d^2*x1^2*x2^2*y1^2*y2^2)^2) by (repeat rewriteAny; field). + assert (HT2: T = (a * ((x1 * y2 + y1 * x2) * (1 - d * x1 * x2 * y1 * y2)) ^ 2 +( + (y1 * y2 - a * x1 * x2) * (1 + d * x1 * x2 * y1 * y2)) ^ 2 -d * ((x1 * + y2 + y1 * x2)* (y1 * y2 - a * x1 * x2))^2)) by (subst; field). + replace 1 with (a*x3^2 + y3^2 -d*x3^2*y3^2); [field|]; subst x3 y3. + + match goal with [ |- ?x = 1 ] => replace x with + ((a * ((x1 * y2 + y1 * x2) * (1 - d * x1 * x2 * y1 * y2)) ^ 2 + + ((y1 * y2 - a * x1 * x2) * (1 + d * x1 * x2 * y1 * y2)) ^ 2 - + d*((x1 * y2 + y1 * x2) * (y1 * y2 - a * x1 * x2)) ^ 2)/ + ((1-d^2*x1^2*x2^2*y1^2*y2^2)^2)) end; try field; auto. + - rewrite <-HT1, <-HT2; field; rewrite HT1; + replace ((1 - d ^ 2 * x1 ^ 2 * x2 ^ 2 * y1 ^ 2 * y2 ^ 2)) + with ((1 - d*x1*x2*y1*y2)*(1 + d*x1*x2*y1*y2)) + by field; simpl; auto. + - replace (1 - (d * x1 * x2 * y1 * y2) ^ 2) + with ((1 - d*x1*x2*y1*y2)*(1 + d*x1*x2*y1*y2)) + by field; auto. + Qed. + + Lemma unifiedAdd'_onCurve' : forall P1 P2, onCurve P1 -> onCurve P2 -> + onCurve (unifiedAdd' P1 P2). + Proof. + intros; destruct P1, P2. + remember (unifiedAdd' (g, g0) (g1, g2)) as p; destruct p. + eapply unifiedAdd'_onCurve; eauto. + Qed. + + Definition unifiedAdd (P1 P2 : point) : point := let 'exist P1' pf1 := P1 in let 'exist P2' pf2 := P2 in - mkPoint (unifiedAdd' P1' P2') _). - Proof. - destruct P1' as [x1 y1], P2' as [x2 y2]; unfold unifiedAdd', onCurve. - admit. (* field will likely work here, but I have not done this by hand *) - Defined. + mkPoint (unifiedAdd' P1' P2') (unifiedAdd'_onCurve' _ _ pf1 pf2). Local Infix "+" := unifiedAdd. Fixpoint scalarMult (n:nat) (P : point) : point := @@ -179,18 +340,6 @@ End CompleteTwistedEdwardsPointFormat. Module CompleteTwistedEdwardsFacts (M : Modulus) (Import P : TwistedEdwardsParams M). Local Open Scope GF_scope. Module Import Curve := CompleteTwistedEdwardsCurve M P. - Lemma twistedAddCompletePlus : forall (P1 P2:point), - let '(x1, y1) := proj1_sig P1 in - let '(x2, y2) := proj1_sig P2 in - (1 + d*x1*x2*y1*y2) <> 0. - (* "Twisted Edwards Curves" <http://eprint.iacr.org/2008/013.pdf> section 6 *) - Admitted. - Lemma twistedAddCompleteMinus : forall (P1 P2:point), - let '(x1, y1) := proj1_sig P1 in - let '(x2, y2) := proj1_sig P2 in - (1 - d*x1*x2*y1*y2) <> 0. - (* "Twisted Edwards Curves" <http://eprint.iacr.org/2008/013.pdf> section 6 *) - Admitted. Lemma point_eq : forall x1 x2 y1 y2, x1 = x2 -> y1 = y2 -> @@ -199,7 +348,7 @@ Module CompleteTwistedEdwardsFacts (M : Modulus) (Import P : TwistedEdwardsParam Proof. intros; subst; f_equal. apply (UIP_dec). (* this is a hack. We actually don't care about the equality of the proofs. However, we *can* prove it, and knowing it lets us use the universal equality instead of a type-specific equivalence, which makes many things nicer. *) - admit. (* GF_eq_dec *) + apply GF_eq_dec. Qed. Hint Resolve point_eq. @@ -221,7 +370,12 @@ Module CompleteTwistedEdwardsFacts (M : Modulus) (Import P : TwistedEdwardsParam (* http://math.rice.edu/~friedl/papers/AAELLIPTIC.PDF *) Admitted. + Lemma zeroIsIdentity' : forall P, unifiedAdd' P (proj1_sig zero) = P. + unfold unifiedAdd', zero; simpl; intros; break_let; f_equal; field; auto. + Qed. + Lemma zeroIsIdentity : forall P, P + zero = P. + (* Should follow from zeroIsIdentity', but dependent types... *) Admitted. Hint Resolve zeroIsIdentity. @@ -353,11 +507,12 @@ Module CompleteTwistedEdwardsFacts (M : Modulus) (Import P : TwistedEdwardsParam End CompleteTwistedEdwardsFacts. Module Type Minus1Params (Import M : Modulus) <: TwistedEdwardsParams M. - Module Export GFDefs := GaloisDefs M. + Module Export GFDefs := ZGaloisField M. Local Open Scope GF_scope. + Axiom char_gt_2 : inject 2 <> 0. Definition a := inject (- 1). Axiom a_nonzero : a <> 0. - Axiom a_square : exists x, x * x = a. + Axiom a_square : exists sqrt_a, sqrt_a^2 = a. Parameter d : GF. Axiom d_nonsquare : forall x, x * x <> d. End Minus1Params. @@ -382,12 +537,14 @@ Module Minus1Format (M : Modulus) (Import P : Minus1Params M) <: CompleteTwisted Hint Unfold projectiveToTwisted twistedToProjective. Lemma GFdiv_1 : forall x, x/1 = x. - Admitted. + Proof. + intros; field; auto. + Qed. Hint Resolve GFdiv_1. Lemma twistedProjectiveInv P : projectiveToTwisted (twistedToProjective P) = P. Proof. - twisted; eapply GFdiv_1. + twisted; eauto. Qed. (** [extended] represents a point on an elliptic curve using extended projective @@ -397,13 +554,7 @@ Module Minus1Format (M : Modulus) (Import P : Minus1Params M) <: CompleteTwisted Definition point := extended. Local Notation "'(' X ',' Y ',' Z ',' T ')'" := (mkExtended (X, Y, Z) T). Definition extendedValid (P : point) : Prop := - let pP := extendedToProjective P in - let X := projectiveX pP in - let Y := projectiveY pP in - let Z := projectiveZ pP in - let T := extendedT P in - T = X*Y/Z. - + let '(X, Y, Z, T) := P in T = X*Y/Z. Definition twistedToExtended (P : (GF*GF)) : point := let '(x, y) := P in (x, y, 1, x*y). @@ -450,21 +601,12 @@ Module Minus1Format (M : Modulus) (Import P : Minus1Params M) <: CompleteTwisted Local Notation "2" := (1+1). (** Second equation from <http://eprint.iacr.org/2008/522.pdf> section 3.1, also <https://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3> and <https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03> *) Definition unifiedAdd (P1 P2 : point) : point := - let k := 2 * d in - let pP1 := extendedToProjective P1 in - let X1 := projectiveX pP1 in - let Y1 := projectiveY pP1 in - let Z1 := projectiveZ pP1 in - let T1 := extendedT P1 in - let pP2 := extendedToProjective P2 in - let X2 := projectiveX pP2 in - let Y2 := projectiveY pP2 in - let Z2 := projectiveZ pP2 in - let T2 := extendedT P2 in + let '(X1, Y1, Z1, T1) := P1 in + let '(X2, Y2, Z2, T2) := P2 in let A := (Y1-X1)*(Y2-X2) in let B := (Y1+X1)*(Y2+X2) in - let C := T1*k*T2 in - let D := Z1*2*Z2 in + let C := T1*2*d*T2 in + let D := Z1*2 *Z2 in let E := B-A in let F := D-C in let G := D+C in @@ -487,22 +629,9 @@ Module Minus1Format (M : Modulus) (Import P : Minus1Params M) <: CompleteTwisted destruct P1 as [[X1 Y1 Z1] T1]. destruct P2 as [[X2 Y2 Z2] T2]. destruct P3 as [[X3 Y3 Z3] T3]. - unfold extendedValid, extendedToProjective, projectiveToTwisted in *. invcs HeqP3. - subst. - (* field. -- fails. but it works in sage: -sage -c 'var("d X1 X2 Y1 Y2 Z1 Z2"); -print(bool((((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * -((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) == -((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2)) * -(2 * Z1 * Z2 - 2 * ((0 - d) / a) * (X1 * Y1 / Z1) * (X2 * Y2 / Z2)) * -((2 * Z1 * Z2 + 2 * ((0 - d) / a) * (X1 * Y1 / Z1) * (X2 * Y2 / Z2)) * -((Y1 + X1) * (Y2 + X2) - (Y1 - X1) * (Y2 - X2))) / -((2 * Z1 * Z2 - 2 * ((0 - d) / a) * (X1 * Y1 / Z1) * (X2 * Y2 / Z2)) * -(2 * Z1 * Z2 + 2 * ((0 - d) / a) * (X1 * Y1 / Z1) * (X2 * Y2 / Z2))))))' - Outputs: - True - *) + field. + (* TODO: prove that denominators are nonzero *) Admitted. Ltac extended0 := repeat progress (autounfold; simpl); intros; |