diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | .make/cc.mk | 20 | ||||
-rw-r--r-- | .make/coq.mk | 28 | ||||
-rw-r--r-- | Makefile | 30 | ||||
-rw-r--r-- | _CoqProject | 23 | ||||
-rw-r--r-- | src/Curves/Curve25519.v | 33 | ||||
-rw-r--r-- | src/Curves/PointFormats.v | 156 | ||||
-rw-r--r-- | src/Galois/AbstractGaloisField.v | 14 | ||||
-rw-r--r-- | src/Galois/ComputationalGaloisField.v | 52 | ||||
-rw-r--r-- | src/Galois/EdDSA.v | 15 | ||||
-rw-r--r-- | src/Galois/Galois.v | 54 | ||||
-rw-r--r-- | src/Galois/GaloisExamples.v | 73 | ||||
-rw-r--r-- | src/Galois/GaloisField.v (renamed from src/Galois/ZGaloisField.v) | 38 | ||||
-rw-r--r-- | src/Galois/GaloisRep.v | 3 | ||||
-rw-r--r-- | src/Galois/GaloisTheory.v | 57 | ||||
-rw-r--r-- | src/Galois/GaloisTutorial.v | 106 | ||||
-rw-r--r-- | src/Galois/ModularBaseSystem.v | 17 | ||||
-rw-r--r-- | src/Rep/BinGF.v | 139 | ||||
-rw-r--r-- | src/Rep/ECRep.v | 12 | ||||
-rw-r--r-- | src/Rep/GaloisRep.v | 8 | ||||
-rw-r--r-- | src/Specific/EdDSA25519.v | 12 | ||||
-rw-r--r-- | src/Specific/GF25519.v | 2 |
22 files changed, 433 insertions, 462 deletions
diff --git a/.gitignore b/.gitignore index cec91e9a6..ff148cbf2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ bedrock fiat *~ +*.vo +*.d +Makefile.coq diff --git a/.make/cc.mk b/.make/cc.mk deleted file mode 100644 index 58724089a..000000000 --- a/.make/cc.mk +++ /dev/null @@ -1,20 +0,0 @@ -# © 2012–2015 the Massachusetts Institute of Technology -# @author bbaren - -CC = clang -CXX = clang++ - -CPPFLAGS = \ - -Wall \ - -D_FORTIFY_SOURCE=2 - -CXXFLAGS = \ - -std=c++11 \ - -ftrapv \ - -fstack-protector-strong --param=ssp-buffer-size=4 \ - -fPIC \ - -O2 -g \ - -ffunction-sections -fdata-sections \ - -Weverything -Wno-c++98-compat - -LDFLAGS = -fPIE -pie diff --git a/.make/coq.mk b/.make/coq.mk deleted file mode 100644 index bab225be7..000000000 --- a/.make/coq.mk +++ /dev/null @@ -1,28 +0,0 @@ -# © 2012–2015 the Massachusetts Institute of Technology -# @author bbaren + rsloan - -COQC = coqc -COQDEP = coqdep - -COMPILE.v = $(COQC) -q $(COQLIBS) - -.PHONY: check_fiat check_bedrock - -check_fiat: - @perl -e \ - 'if(! -d "./fiat") { print("you need to link fiat to ./fiat\n"); exit(1) }' - -check_bedrock: - @perl -e \ - 'if(! -d "./bedrock") { print("you need to link bedrock to ./bedrock\n"); exit(1) }' - -%.vo %.glob: %.v.d - $(COMPILE.v) $* - -%.v.d: %.v - @$(COQDEP) -I . $(COQLIBS) "$<" >"$@" \ - || (RV=$$?; rm -f "$@"; exit $${RV}) - -define coq-generated -$1.vo $1.v.d $1.glob -endef @@ -1,19 +1,25 @@ -# © 2015 the Massachusetts Institute of Technology -# @author bbaren + rsloan +COQ_ARGS := -R fiat/src Fiat -R bedrock/Bedrock Bedrock +MOD_NAME := Crypto +SRC_DIR := src +MODULES := Curves Galois Rep Specific Tactics Util -SOURCES := $(shell grep -v '^-' _CoqProject | tr '\n' ' ') -COQLIBS := $(shell grep '^-' _CoqProject | tr '\n' ' ') +VS := $(MODULES:%=src/%/*.v) -include .make/cc.mk -include .make/coq.mk +.PHONY: coq clean install +.DEFAULT_GOAL: coq -FAST_TARGETS += check_fiat check_bedrock clean +coq: Makefile.coq + $(MAKE) -f Makefile.coq -.DEFAULT_GOAL = all -.PHONY: clean coquille +Makefile.coq: Makefile $(VS) + coq_makefile -R $(SRC_DIR) $(MOD_NAME) $(COQ_ARGS) $(VS) -o Makefile.coq -all: check_fiat check_bedrock $(SOURCES:%=%o) +clean: Makefile.coq + $(MAKE) -f Makefile.coq clean + rm -f Makefile.coq -clean: - $(RM) $(foreach f,$(SOURCES),$(call coq-generated,$(basename $f))) +install: coq + ln -sfL $(shell pwd)/src $(shell coqtop -where)/user-contrib/Crypto + ln -sfL $(shell pwd)/fiat/src $(shell coqtop -where)/user-contrib/Fiat + ln -sfL $(shell pwd)/bedrock/Bedrock $(shell coqtop -where)/user-contrib/Bedrock diff --git a/_CoqProject b/_CoqProject deleted file mode 100644 index d5e2c1c89..000000000 --- a/_CoqProject +++ /dev/null @@ -1,23 +0,0 @@ --R src Crypto --R fiat/src Fiat --R bedrock/Bedrock Bedrock -src/Tactics/VerdiTactics.v -src/Util/CaseUtil.v -src/Util/ListUtil.v -src/Util/NatUtil.v -src/Util/ZUtil.v -src/Util/NumTheoryUtil.v -src/Galois/Galois.v -src/Galois/GaloisTheory.v -src/Galois/ZGaloisField.v -src/Galois/GaloisExamples.v -src/Galois/AbstractGaloisField.v -src/Galois/ComputationalGaloisField.v -src/Galois/BaseSystem.v -src/Galois/ModularBaseSystem.v -src/Curves/PointFormats.v -src/Galois/EdDSA.v -src/Assembly/WordBounds.v -src/Curves/Curve25519.v -src/Specific/GF25519.v -src/Specific/EdDSA25519.v diff --git a/src/Curves/Curve25519.v b/src/Curves/Curve25519.v index 4162d4c1c..248e0af6e 100644 --- a/src/Curves/Curve25519.v +++ b/src/Curves/Curve25519.v @@ -1,6 +1,5 @@ Require Import Zpower ZArith Znumtheory. -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory Crypto.Galois.ComputationalGaloisField. -Require Import Crypto.Galois.ZGaloisField. +Require Import Crypto.Galois.GaloisField. Require Import Crypto.Curves.PointFormats. Definition two_255_19 := 2^255 - 19. (* <http://safecurves.cr.yp.to/primeproofs.html> *) @@ -10,13 +9,9 @@ Module Modulus25519 <: Modulus. End Modulus25519. Module Curve25519Params <: TwistedEdwardsParams Modulus25519 <: Minus1Params Modulus25519. - Module Import GFDefs := ZGaloisField Modulus25519. - - Lemma char_gt_2 : inject 2 <> 0%GF. - Admitted. + Module Import GFDefs := GaloisField Modulus25519. Local Open Scope GF_scope. - Coercion inject : Z >-> GF. Definition a : GF := -1. Definition d : GF := -121665 / 121666. @@ -26,14 +21,24 @@ Module Curve25519Params <: TwistedEdwardsParams Modulus25519 <: Minus1Params Mod discriminate. Qed. - Lemma a_square : exists x, x * x = a. + Definition sqrt_a: GF := 19681161376707505956807079304988542015446066515923890162744021073123829784752. + + Lemma a_square : sqrt_a^2 = a. Proof. - unfold a. - exists 19681161376707505956807079304988542015446066515923890162744021073123829784752. - (* vm_compute runs out of memory. *) + (* An example of how to use ring properly *) + replace (sqrt_a ^ 2) with (sqrt_a * sqrt_a) by ring. + assert ((inject ((GFToZ sqrt_a) * (GFToZ sqrt_a)))%Z = a). + + - apply gf_eq. + (* vm_compute runs out of memory. *) + admit. + + - rewrite inject_distr_mul in H. + intuition. + Admitted. - Lemma d_nonsquare : forall x, x * x <> d. + Lemma d_nonsquare : forall x, x * x <> d. (* <https://en.wikipedia.org/wiki/Euler%27s_criterion> *) Admitted. @@ -53,6 +58,10 @@ Module Curve25519Params <: TwistedEdwardsParams Modulus25519 <: Minus1Params Mod *) Definition basepointY := 4 / 5. + + (* True iff this prime is odd *) + Definition char_gt_2: (1+1) <> 0. + Admitted. End Curve25519Params. Module Edwards25519 := CompleteTwistedEdwardsCurve Modulus25519 Curve25519Params. diff --git a/src/Curves/PointFormats.v b/src/Curves/PointFormats.v index 32e6acdd0..cd27a2033 100644 --- a/src/Curves/PointFormats.v +++ b/src/Curves/PointFormats.v @@ -1,15 +1,16 @@ -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory Crypto.Galois.ZGaloisField. -Require Import Tactics.VerdiTactics. -Require Import Logic.Eqdep_dec. -Require Import BinNums NArith. +Require Import Crypto.Galois.GaloisTheory Crypto.Galois.GaloisField. +Require Import Crypto.Tactics.VerdiTactics. +Require Import Logic Logic.Eqdep_dec. +Require Import BinNums NArith Nnat ZArith. Module Type TwistedEdwardsParams (M : Modulus). - Module Export GFDefs := ZGaloisField M. + Module Export GFDefs := GaloisField M. Local Open Scope GF_scope. - Axiom char_gt_2 : inject 2 <> 0. + Axiom char_gt_2 : (1+1) <> 0. Parameter a : GF. Axiom a_nonzero : a <> 0. - Axiom a_square : exists sqrt_a, sqrt_a^2 = a. + Parameter sqrt_a : GF. + Axiom a_square : sqrt_a^2 = a. Parameter d : GF. Axiom d_nonsquare : forall x, x * x <> d. End TwistedEdwardsParams. @@ -104,7 +105,7 @@ Qed. Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParams M). Local Open Scope GF_scope. - (** Twisted Ewdwards curves with complete addition laws. References: + (** Twisted Edwards curves with complete addition laws. References: * <https://eprint.iacr.org/2008/013.pdf> * <http://ed25519.cr.yp.to/ed25519-20110926.pdf> * <https://eprint.iacr.org/2015/677.pdf> @@ -133,22 +134,104 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam (* 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. + (* NOTE: these should serve as an example for using field *) + Lemma mul_nonzero_l : forall a b, a*b <> 0 -> a <> 0. - Admitted. + intros; intuition; subst. + assert (0 * b = 0) by field; intuition. + Qed. + 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. + intros; intuition; subst. + assert (a0 * 0 = 0) by field; intuition. + Qed. + Definition GF_eq_dec : forall x y : GF, {x = y} + {x <> y}. - Admitted. + intros. + assert (H := Z.eq_dec (inject x) (inject y)). + + destruct H. + + - left; galois; intuition. + + - right; intuition. + rewrite H in n. + assert (y = y); intuition. + Qed. + + Lemma mul_zero_why : forall a b, a*b = 0 -> a = 0 \/ b = 0. + intros. + assert (Z := GF_eq_dec a0 0); destruct Z. + + - left; intuition. + + - assert (a0 * b / a0 = 0) by + ( rewrite H; field; intuition ). + + field_simplify in H0. + replace (b/1) with b in H0 by (field; intuition). + right; intuition. + apply n in H0; intuition. + Qed. + + Lemma mul_nonzero_nonzero : forall a b, a <> 0 -> b <> 0 -> a*b <> 0. + intros; intuition; subst. + apply mul_zero_why in H1. + destruct H1; subst; intuition. + Qed. Hint Resolve mul_nonzero_nonzero. + Lemma root_zero : forall (x: GF) (p: N), x^p = 0 -> x = 0. + intros. + + induction p; inversion H. + + revert H H1; generalize x; induction p; intros. + + - simpl in H; apply mul_zero_why in H; destruct H; intuition. + + + subst; intuition. + + + apply IHp in H. + rewrite H1. + simpl in H1. + apply mul_zero_why in H1; destruct H1; intuition. + rewrite H0 in H. + apply mul_zero_why in H; destruct H; intuition. + + simpl; intuition. + + - simpl in H1; apply IHp in H1; simpl; intuition. + simpl in H; rewrite H in H1; rewrite H. + apply mul_zero_why in H1; destruct H1; intuition. + + - simpl in H; subst; intuition. + + Qed. + + Lemma root_nonzero : forall x p, x^p <> 0 -> (p <> 0)%N -> x <> 0. + intros; intuition. + + induction p. + + - apply H; intuition. + + - apply H. + rewrite H1 in *. + induction p. + + + simpl. + field. + + + simpl in *. + replace (0 * 0) with 0 in * by field. + apply IHp; intuition. + induction p; inversion H2. + + + simpl; intuition. + + Qed. + Ltac whatsNotZero := repeat match goal with | [H: ?lhs = ?rhs |- _ ] => @@ -159,7 +242,10 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam 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) + let Y:=fresh in let Z:=fresh in try ( + assert (p <> 0%N) as Z by (intro Y; inversion Y); + assert (a <> 0) by (eapply root_nonzero; eauto); + clear Z) | [H: (?a*?b)%GF <> 0 |- _ ] => match goal with [Ha: a <> 0 |- _ ] => fail 1 | _ => idtac end; assert (a <> 0) by (eapply mul_nonzero_l; eauto) @@ -173,11 +259,14 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam onCurve (x2, y2) -> (d*x1*x2*y1*y2)^2 <> 1. Proof. + (* TODO: this proof was made inconsistent by an actually + correct version of root_nonzero. This adds the necessary + hypothesis*) 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 *. + rewrite a_square in Ha_nonzero. (* Furthermore... *) pose proof (eq_refl (d*x1^2*y1^2*(sqrt_a^2*x2^2 + y2^2))) as Heqt. @@ -206,13 +295,18 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam end. assert (Hc: (sqrt_a * x2 + y2) + (sqrt_a * x2 - y2) = 0) by (repeat rewriteAny; field). + + rewrite a_square in *. 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. + 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. + + + replace (inject 2%Z) with (1+1) in Hccc by field; intuition. + + + rewrite <- a_square; simpl; rewrite Hccc; field. Qed. - Lemma edwardsAddCompletePlus x1 y1 x2 y2 : onCurve (x1,y1) -> onCurve (x2, y2) -> @@ -239,8 +333,8 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam Definition projX (P:point) := fst (proj1_sig P). Definition projY (P:point) := snd (proj1_sig P). - Definition checkOnCurve x y : if Zbool.Zeq_bool (a*x^2 + y^2) (1 + d*x^2*y^2) then point else True. - break_if. exists (x, y). exact (GFdecidable _ _ Heqb). trivial. + Definition checkOnCurve (x y: GF) : if Zbool.Zeq_bool (a*x^2 + y^2)%GF (1 + d*x^2*y^2)%GF then point else True. + break_if; trivial. exists (x, y). apply GFdecidable. exact Heqb. Defined. Hint Unfold onCurve mkPoint. @@ -259,6 +353,7 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam 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 := @@ -281,7 +376,7 @@ Module CompleteTwistedEdwardsCurve (M : Modulus) (Import P : TwistedEdwardsParam ((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; + - 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. @@ -507,12 +602,13 @@ Module CompleteTwistedEdwardsFacts (M : Modulus) (Import P : TwistedEdwardsParam End CompleteTwistedEdwardsFacts. Module Type Minus1Params (Import M : Modulus) <: TwistedEdwardsParams M. - Module Export GFDefs := ZGaloisField M. + Module Export GFDefs := GaloisField M. Local Open Scope GF_scope. - Axiom char_gt_2 : inject 2 <> 0. + Axiom char_gt_2 : (1+1) <> 0. Definition a := inject (- 1). Axiom a_nonzero : a <> 0. - Axiom a_square : exists sqrt_a, sqrt_a^2 = a. + Parameter sqrt_a : GF. + Axiom a_square : sqrt_a^2 = a. Parameter d : GF. Axiom d_nonsquare : forall x, x * x <> d. End Minus1Params. diff --git a/src/Galois/AbstractGaloisField.v b/src/Galois/AbstractGaloisField.v deleted file mode 100644 index 12a9af80d..000000000 --- a/src/Galois/AbstractGaloisField.v +++ /dev/null @@ -1,14 +0,0 @@ - -Require Import BinInt BinNat ZArith Znumtheory. -Require Import Eqdep_dec. -Require Import Tactics.VerdiTactics. -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory. - -Module AbstractGaloisField (M: Modulus). - Module G := Galois M. - Module T := GaloisTheory M. - Export M G T. - - Add Field GFfield_computational : GFfield_theory - (power_tac GFpower_theory [GFexp_tac]). -End AbstractGaloisField. diff --git a/src/Galois/ComputationalGaloisField.v b/src/Galois/ComputationalGaloisField.v deleted file mode 100644 index e83e22fea..000000000 --- a/src/Galois/ComputationalGaloisField.v +++ /dev/null @@ -1,52 +0,0 @@ - -Require Import BinInt BinNat ZArith Znumtheory. -Require Import Eqdep_dec. -Require Import Tactics.VerdiTactics. -Require Import Galois GaloisTheory. - -Module ComputationalGaloisField (M: Modulus). - Module G := Galois M. - Module T := GaloisTheory M. - Export M G T. - - Ltac isModulusConstant := - let hnfModulus := eval hnf in (proj1_sig modulus) - in match (isZcst hnfModulus) with - | NotConstant => NotConstant - | _ => match hnfModulus with - | Z.pos _ => true - | _ => false - end - end. - - Ltac isGFconstant t := - match t with - | GFzero => true - | GFone => true - | ZToGF _ => isModulusConstant - | exist _ ?z _ => match (isZcst z) with - | NotConstant => NotConstant - | _ => isModulusConstant - end - | _ => NotConstant - end. - - Ltac GFconstants t := - match isGFconstant t with - | NotConstant => NotConstant - | _ => t - end. - - Add Ring GFring_computational : GFring_theory - (decidable GFdecidable, - constants [GFconstants], - div GFdiv_theory, - power_tac GFpower_theory [GFexp_tac]). - - Add Field GFfield_computational : GFfield_theory - (decidable GFdecidable, - completeness GFcomplete, - constants [GFconstants], - div GFdiv_theory, - power_tac GFpower_theory [GFexp_tac]). -End ComputationalGaloisField. diff --git a/src/Galois/EdDSA.v b/src/Galois/EdDSA.v index de26c678c..68b8867b8 100644 --- a/src/Galois/EdDSA.v +++ b/src/Galois/EdDSA.v @@ -1,7 +1,7 @@ Require Import ZArith NPeano. Require Import Bedrock.Word. Require Import Crypto.Curves.PointFormats. -Require Import Crypto.Galois.BaseSystem Crypto.Galois.ZGaloisField Crypto.Galois.GaloisTheory. +Require Import Crypto.Galois.BaseSystem Crypto.Galois.GaloisField. Require Import Util.ListUtil Util.CaseUtil Util.ZUtil. Require Import VerdiTactics. @@ -54,7 +54,7 @@ Module Type EdDSAParams. Axiom n_ge_c : n >= c. Axiom n_le_b : n <= b. - Module Import GFDefs := ZGaloisField Modulus_q. + Module Import GFDefs := GaloisField Modulus_q. Local Open Scope GF_scope. (* Secret EdDSA scalars have exactly n + 1 bits, with the top bit @@ -66,8 +66,9 @@ Module Type EdDSAParams. * on average to determine an EdDSA secret key from an EdDSA public key *) Parameter a : GF. + Parameter sqrt_a : GF. Axiom a_nonzero : a <> 0%GF. - Axiom a_square : exists x, x * x = a. + Axiom a_square : sqrt_a^2 = a. (* The usual recommendation for best performance is a = −1 if q mod 4 = 1, * and a = 1 if q mod 4 = 3. * The original specification of EdDSA did not include this parameter: @@ -81,13 +82,17 @@ Module Type EdDSAParams. (* E = {(x, y) \in Fq x Fq : ax^2 + y^2 = 1 + dx^2y^2}. * This set forms a group with neutral element 0 = (0, 1) under the * twisted Edwards addition law. *) + + (* We have an odd prime *) + Axiom char_gt_2: 1+1 <> 0. + Module CurveParameters <: TwistedEdwardsParams Modulus_q. Module GFDefs := GFDefs. - Definition char_gt_2 : inject 2 <> 0. - Admitted. (* follows from q_odd *) Definition a : GF := a. Definition a_nonzero := a_nonzero. Definition a_square := a_square. + Definition char_gt_2 := char_gt_2. + Definition sqrt_a := sqrt_a. Definition d := d. Definition d_nonsquare := d_nonsquare. End CurveParameters. diff --git a/src/Galois/Galois.v b/src/Galois/Galois.v index 4fd151d36..86ce7f05e 100644 --- a/src/Galois/Galois.v +++ b/src/Galois/Galois.v @@ -3,24 +3,59 @@ Require Import BinInt BinNat ZArith Znumtheory. Require Import Eqdep_dec. Require Import Tactics.VerdiTactics. +(* This file is for the high-level type definitions of + * GF, Primes, Moduli, etc. and their notations and essential + * operations. + * + * The lemmas required for the ring and field theories are + * in GaloisTheory.v and the actual tactic implementations + * for the field are in GaloisField.v. An introduction to the + * use of our implementation of the Galois field is in + * GaloisTutorial.v + *) + Section GaloisPreliminaries. + (* The core prime modulus type, relying on Znumtheory's prime *) Definition Prime := {x: Z | prime x}. + (* Automagically coerce primes to Z *) Definition primeToZ(x: Prime) := proj1_sig x. Coercion primeToZ: Prime >-> Z. End GaloisPreliminaries. +(* A module to hold the field's modulus, which will be an argument to + * all of our Galois modules. + *) Module Type Modulus. Parameter modulus: Prime. End Modulus. +(* The core Galois Field model *) Module Galois (M: Modulus). Import M. + (* The sigma definition of an element of the field: we have + * an element corresponding to the values in Z which can be + * produced by a 'mod' operation. + *) Definition GF := {x: Z | x = x mod modulus}. + + Delimit Scope GF_scope with GF. + Local Open Scope GF_scope. + + (* Automagically convert GF to Z when needed *) Definition GFToZ(x: GF) := proj1_sig x. Coercion GFToZ: GF >-> Z. + (* Automagically convert Z to GF when needed *) + Definition inject(x: Z): GF. + exists (x mod modulus). + abstract (rewrite Zmod_mod; trivial). + Defined. + + Coercion inject : Z >-> GF. + + (* Convert Z to GF without a mod operation, for when the modulus is opaque *) Definition ZToGF (x: Z) : if ((0 <=? x) && (x <? modulus))%bool then GF else True. break_if; [|trivial]. exists x. @@ -31,6 +66,7 @@ Module Galois (M: Modulus). - rewrite <- Z.ltb_lt; auto. Defined. + (* Core lemma: equality in GF implies equality in Z *) Theorem gf_eq: forall (x y: GF), x = y <-> GFToZ x = GFToZ y. Proof. destruct x, y; intuition; simpl in *; try congruence. @@ -40,7 +76,7 @@ Module Galois (M: Modulus). apply Z.eq_dec. Qed. - (* Elementary operations *) + (* Core values: One and Zero *) Definition GFzero: GF. exists 0. abstract trivial. @@ -60,6 +96,7 @@ Module Galois (M: Modulus). Qed. Hint Resolve GFone_nonzero. + (* Elementary operations: +, -, * *) Definition GFplus(x y: GF): GF. exists ((x + y) mod modulus); abstract (rewrite Zmod_mod; trivial). @@ -77,7 +114,7 @@ Module Galois (M: Modulus). Definition GFopp(x: GF): GF := GFminus GFzero x. - (* Totient Preliminaries *) + (* Modular exponentiation *) Fixpoint GFexp' (x: GF) (power: positive) := match power with | xH => x @@ -91,12 +128,13 @@ Module Galois (M: Modulus). | Npos power' => GFexp' x power' end. - (* Inverses + division derived from the existence of a totient *) + (* Preliminaries to inversion in a prime field *) Definition isTotient(e: N) := N.gt e 0 /\ forall g: GF, g <> GFzero -> GFexp g e = GFone. Definition Totient := {e: N | isTotient e}. + (* Get a totient via Fermat's little theorem *) Theorem fermat_little_theorem: isTotient (N.pred (Z.to_N modulus)). Admitted. @@ -108,8 +146,18 @@ Module Galois (M: Modulus). Definition totientToN(x: Totient) := proj1_sig x. Coercion totientToN: Totient >-> N. + (* Define inversion and division *) Definition GFinv(x: GF): GF := GFexp x (N.pred totient). Definition GFdiv(x y: GF): GF := GFmult x (GFinv y). + (* Notations for all of the operations we just made *) + Notation "1" := GFone : GF_scope. + Notation "0" := GFzero : GF_scope. + Infix "+" := GFplus : GF_scope. + Infix "-" := GFminus : GF_scope. + Infix "*" := GFmult : GF_scope. + Infix "/" := GFdiv : GF_scope. + Infix "^" := GFexp : GF_scope. + End Galois. diff --git a/src/Galois/GaloisExamples.v b/src/Galois/GaloisExamples.v deleted file mode 100644 index 12bcfa2c8..000000000 --- a/src/Galois/GaloisExamples.v +++ /dev/null @@ -1,73 +0,0 @@ - -Require Import Zpower ZArith Znumtheory. -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory. -Require Import Crypto.Galois.ZGaloisField. - -Definition two_5_1 := (two_p 5) - 1. -Lemma two_5_1_prime : prime two_5_1. -Admitted. - -Definition two_127_1 := (two_p 127) - 1. -Lemma two_127_1_prime : prime two_127_1. -Admitted. - -Module Modulus31 <: Modulus. - Definition modulus := exist _ two_5_1 two_5_1_prime. -End Modulus31. - -Module Modulus127_1 <: Modulus. - Definition modulus := exist _ two_127_1 two_127_1_prime. -End Modulus127_1. - -Module Example31. - Module Theory := ZGaloisField Modulus31. - Import Theory. - Local Open Scope GF_scope. - - Lemma example1: forall x y z: GF, z <> 0 -> x * (y / z) / z = x * y / (z ^ 2). - Proof. - intros; simpl. - field; trivial. - Qed. - - Lemma example2: forall x: GF, x * (inject 2) = x + x. - Proof. - intros; simpl. - field. - Qed. - - Lemma example3: forall x: GF, x ^ 2 + (inject 2) * x + (inject 1) = (x + (inject 1)) ^ 2. - Proof. - intros; simpl. - field; trivial. - Qed. - - Lemma example4: forall x: GF, x/(inject 1) = x. - Proof. - intros; field. - discriminate. - Qed. - -End Example31. - -Module TimesZeroTransparentTestModule. - Module Theory := ZGaloisField Modulus127_1. - Import Theory. - Local Open Scope GF_scope. - - Lemma timesZero : forall a, a*0 = 0. - intros. - field. - Qed. -End TimesZeroTransparentTestModule. - -Module TimesZeroParametricTestModule (M: Modulus). - Module Theory := ZGaloisField M. - Import Theory. - Local Open Scope GF_scope. - - Lemma timesZero : forall a, a*0 = 0. - intros. - field. - Qed. -End TimesZeroParametricTestModule. diff --git a/src/Galois/ZGaloisField.v b/src/Galois/GaloisField.v index a554e826a..d87e35dc4 100644 --- a/src/Galois/ZGaloisField.v +++ b/src/Galois/GaloisField.v @@ -1,13 +1,27 @@ Require Import BinInt BinNat ZArith Znumtheory. Require Import BoolEq Field_theory. -Require Import Galois GaloisTheory. -Require Import Tactics.VerdiTactics. +Require Export Crypto.Galois.Galois Crypto.Galois.GaloisTheory. +Require Import Crypto.Tactics.VerdiTactics. -Module ZGaloisField (M: Modulus). +(* This file is for the actual field tactics and some specialized + * morphisms that help field operate. + * + * When you want a Galois Field, this is the /only module/ you + * should import, because it automatically pulls in everything + * from Galois and the Modulus. + *) +Module GaloisField (M: Modulus). Module G := Galois M. Module T := GaloisTheory M. Export M G T. + (* Define a "ring morphism" between GF and Z, i.e. an equivalence + * between 'inject (ZFunction (X))' and 'GFFunction (inject (X))'. + * + * Doing this allows us to do our coefficient manipulations in Z + * rather than GF, because we know it's equivalent to inject the + * result afterward. + *) Lemma GFring_morph: ring_morph GFzero GFone GFplus GFmult GFminus GFopp eq 0%Z 1%Z Zplus Zmult Zminus Zopp Zeq_bool @@ -26,6 +40,7 @@ Module ZGaloisField (M: Modulus). symmetry; apply Zeq_bool_eq; trivial. Qed. + (* Redefine our division theory under the ring morphism *) Lemma GFmorph_div_theory: div_theory eq Zplus Zmult inject Z.quotrem. Proof. @@ -38,6 +53,7 @@ Module ZGaloisField (M: Modulus). destruct a; simpl; trivial. Qed. + (* Some simple utility lemmas *) Lemma injectZeroIsGFZero : GFzero = inject 0. Proof. @@ -57,10 +73,18 @@ Module ZGaloisField (M: Modulus). intuition; solve_by_inversion. Qed. + (* Change all GFones to (inject 1) and GFzeros to (inject 0) so that + * we can use our ring morphism to simplify them + *) Ltac GFpreprocess := repeat rewrite injectZeroIsGFZero; repeat rewrite injectOneIsGFOne. + (* Split up the equation (because field likes /\, then + * change back all of our GFones and GFzeros. + * + * TODO (adamc): what causes it to generate these subproofs? + *) Ltac GFpostprocess := repeat split; repeat match goal with [ |- context[exist ?a ?b (inject_subproof ?x)] ] => @@ -69,18 +93,21 @@ Module ZGaloisField (M: Modulus). repeat rewrite <- injectZeroIsGFZero; repeat rewrite <- injectOneIsGFOne. + (* Tactic to passively convert from GF to Z in special circumstances *) Ltac GFconstant t := match t with | inject ?x => x | _ => NotConstant end. + (* Add our ring with all the fixin's *) Add Ring GFring_Z : GFring_theory (morphism GFring_morph, constants [GFconstant], div GFmorph_div_theory, - power_tac GFpower_theory [GFexp_tac]). + power_tac GFpower_theory [GFexp_tac]). + (* Add our field with all the fixin's *) Add Field GFfield_Z : GFfield_theory (morphism GFring_morph, preprocess [GFpreprocess], @@ -88,4 +115,5 @@ Module ZGaloisField (M: Modulus). constants [GFconstant], div GFmorph_div_theory, power_tac GFpower_theory [GFexp_tac]). -End ZGaloisField. + +End GaloisField. diff --git a/src/Galois/GaloisRep.v b/src/Galois/GaloisRep.v index 027d0d27e..4f4dce486 100644 --- a/src/Galois/GaloisRep.v +++ b/src/Galois/GaloisRep.v @@ -1,5 +1,6 @@ -Module Type GaloisRep (). +Module Type GaloisRep . End GaloisRep. + diff --git a/src/Galois/GaloisTheory.v b/src/Galois/GaloisTheory.v index 3cfa0323c..bef7fbe03 100644 --- a/src/Galois/GaloisTheory.v +++ b/src/Galois/GaloisTheory.v @@ -8,21 +8,14 @@ Require Export Crypto.Galois.Galois. Set Implicit Arguments. Unset Strict Implicits. +(* This file is for all the lemmas we need to construct a ring, + * field, power, and division theory on a Galois Field. + *) Module GaloisTheory (M: Modulus). Module G := Galois M. Export M G. - (* Notations *) - Delimit Scope GF_scope with GF. - Notation "1" := GFone : GF_scope. - Notation "0" := GFzero : GF_scope. - Infix "+" := GFplus : GF_scope. - Infix "-" := GFminus : GF_scope. - Infix "*" := GFmult : GF_scope. - Infix "/" := GFdiv : GF_scope. - Infix "^" := GFexp : GF_scope. - - (* Basic Properties *) + (***** Preliminary Tactics *****) (* Fails iff the input term does some arithmetic with mod'd values. *) Ltac notFancy E := @@ -76,6 +69,7 @@ Module GaloisTheory (M: Modulus). end; simpl in *; autorewrite with core; intuition; demod; try solve [ f_equal; intuition ]. + (* Automatically unfold the definition of Z *) Lemma modmatch_eta : forall n, match n with | 0 => 0 @@ -88,10 +82,11 @@ Module GaloisTheory (M: Modulus). Hint Rewrite Zmod_mod modmatch_eta. - (* Ring Theory*) - + (* Substitution to prove all Compats *) Ltac compat := repeat intro; subst; trivial. + (***** Ring Theory *****) + Instance GFplus_compat : Proper (eq==>eq==>eq) GFplus. Proof. compat. @@ -117,10 +112,11 @@ Module GaloisTheory (M: Modulus). constructor; galois. Qed. - (* Power theory *) + (***** Power theory *****) Local Open Scope GF_scope. + (* Separate two of the same base *) Lemma GFexp'_doubling : forall q r0, GFexp' (r0 * r0) q = GFexp' r0 q * GFexp' r0 q. Proof. induction q; simpl; intuition. @@ -129,6 +125,7 @@ Module GaloisTheory (M: Modulus). apply Zmod_eq; ring. Qed. + (* Equivalence with pow_pos for subroutine of GFexp *) Lemma GFexp'_correct : forall r p, GFexp' r p = pow_pos GFmult r p. Proof. induction p; simpl; intuition; @@ -137,12 +134,14 @@ Module GaloisTheory (M: Modulus). Hint Immediate GFexp'_correct. + (* Equivalence with pow_pos for GFexp *) Lemma GFexp_correct : forall r n, r^n = pow_N 1 GFmult r n. Proof. induction n; simpl; intuition. Qed. + (* Equivalence with pow_pos for GFexp with identity (a utility lemma) *) Lemma GFexp_correct' : forall r n, r^id n = pow_N 1 GFmult r n. Proof. @@ -156,10 +155,11 @@ Module GaloisTheory (M: Modulus). constructor; auto. Qed. - (* Ring properties *) + (***** Additional tricks for Ring *****) Ltac GFexp_tac t := Ncst t. + (* Decideability *) Lemma GFdecidable : forall (x y: GF), Zeq_bool x y = true -> x = y. Proof. intros; galois. @@ -167,6 +167,7 @@ Module GaloisTheory (M: Modulus). trivial. Qed. + (* Completeness *) Lemma GFcomplete : forall (x y: GF), x = y -> Zeq_bool x y = true. Proof. intros. @@ -174,40 +175,45 @@ Module GaloisTheory (M: Modulus). galois. Qed. - (* Division Theory *) - Definition inject(x: Z): GF. - exists (x mod modulus). - abstract (demod; trivial). - Defined. + (***** Division Theory *****) + (* Compatibility between inject and addition *) Lemma inject_distr_add : forall (m n : Z), inject (m + n) = inject m + inject n. Proof. galois. Qed. + (* Compatibility between inject and subtraction *) Lemma inject_distr_sub : forall (m n : Z), inject (m - n) = inject m - inject n. Proof. galois. Qed. + (* Compatibility between inject and multiplication *) Lemma inject_distr_mul : forall (m n : Z), inject (m * n) = inject m * inject n. Proof. galois. Qed. + (* Compatibility between inject and GFtoZ *) Lemma inject_eq : forall (x : GF), inject x = x. Proof. galois. Qed. + (* Compatibility between inject and mod *) Lemma inject_mod_eq : forall x, inject x = inject (x mod modulus). Proof. galois. Qed. + (* The main division theory: + * equivalence between division and quotrem (euclidean division) + *) + Definition GFquotrem(a b: GF): GF * GF := match (Z.quotrem a b) with | (q, r) => (inject q, inject r) @@ -225,13 +231,13 @@ Module GaloisTheory (M: Modulus). destruct a; simpl; trivial. Qed. - (* Now add the ring with all modifiers *) + (***** Field Theory *****) + (* First, add the modifiers to our ring *) Add Ring GFring0 : GFring_theory (power_tac GFpower_theory [GFexp_tac]). - (* Field Theory*) - + (* Utility lemmas for multiplicative inverses *) Lemma GFexp'_pred' : forall x p, GFexp' p (Pos.succ x) = GFexp' p x * p. Proof. @@ -258,6 +264,7 @@ Module GaloisTheory (M: Modulus). destruct p0; intuition. Qed. + (* Show that GFinv actually defines multiplicative inverses *) Lemma GF_multiplicative_inverse : forall p, p <> 0 -> GFinv p * p = 1. @@ -269,11 +276,13 @@ Module GaloisTheory (M: Modulus). eapply N.lt_irrefl; eauto using N.gt_lt. Qed. + (* Compatibility of inverses and equality *) Instance GFinv_compat : Proper (eq==>eq) GFinv. Proof. compat. Qed. + (* Compatibility of division and equality *) Instance GFdiv_compat : Proper (eq==>eq==>eq) GFdiv. Proof. compat. @@ -283,9 +292,11 @@ Module GaloisTheory (M: Modulus). Local Hint Extern 1 False => discriminate. + (* Add an abstract field (without modifiers) *) Definition GFfield_theory : field_theory GFzero GFone GFplus GFmult GFminus GFopp GFdiv GFinv eq. Proof. constructor; auto. Qed. + End GaloisTheory. diff --git a/src/Galois/GaloisTutorial.v b/src/Galois/GaloisTutorial.v new file mode 100644 index 000000000..5ef0e4cf5 --- /dev/null +++ b/src/Galois/GaloisTutorial.v @@ -0,0 +1,106 @@ + +Require Import Zpower ZArith Znumtheory. +Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory. +Require Import Crypto.Galois.GaloisField. + +(* First, we define our prime in Z*) +Definition two_5_1 := (two_p 5) - 1. +Definition two_127_1 := (two_p 127) - 1. + +(* Then proofs of their primality *) +Lemma two_5_1_prime : prime two_5_1. +Admitted. + +Lemma two_127_1_prime : prime two_127_1. +Admitted. + +(* And use those to make modulus modules *) +Module Modulus31 <: Modulus. + Definition modulus := exist _ two_5_1 two_5_1_prime. +End Modulus31. + +Module Modulus127_1 <: Modulus. + Definition modulus := exist _ two_127_1 two_127_1_prime. +End Modulus127_1. + +Module Example31. + (* Then we can construct a field with that modulus *) + Module Field := GaloisField Modulus31. + Import Field. + + (* And pull in the appropriate notations *) + Local Open Scope GF_scope. + + (* First, let's solve a ring example*) + Lemma ring_example: forall x: GF, x * 2 = x + x. + Proof. + intros. + ring. + Qed. + + (* Then a field example (we have to know we can't divide by zero!) *) + Lemma field_example: forall x y z: GF, z <> 0 -> + x * (y / z) / z = x * y / (z ^ 2). + Proof. + intros; simpl. + field; trivial. + Qed. + + (* Then an example with exponentiation *) + Lemma exp_example: forall x: GF, x ^ 2 + 2 * x + 1 = (x + 1) ^ 2. + Proof. + intros; simpl. + field; trivial. + Qed. + + (* In general, the rule I've been using is: + + - If our goal looks like x = y: + + + If we need to use assumptions to prove the goal, then before + we apply field, + + * Perform all relevant substitutions (especially subst) + + * If we have something more complex, we're probably going + to have to performe some sequence of "replace X with Y" + and solve out the subgoals manually before we can use + field. + + + Else, just use field directly + + - If we just want to simplify terms and put them into a canonical + form, then field_simplify or ring_simplify should do the trick. + Note, however, that the canonical form has lots of annoying "/1"s + + - Otherwise, do a "replace X with Y" to generate an equality + so that we can use field in the above case + + *) + +End Example31. + +(* Notice that the field tactics work whether we know what the modulus is *) +Module TimesZeroTransparentTestModule. + Module Theory := GaloisField Modulus127_1. + Import Theory. + Local Open Scope GF_scope. + + Lemma timesZero : forall a, a*0 = 0. + intros. + field. + Qed. +End TimesZeroTransparentTestModule. + +(* Or if we don't (i.e. it's opaque) *) +Module TimesZeroParametricTestModule (M: Modulus). + Module Theory := GaloisField M. + Import Theory. + Local Open Scope GF_scope. + + Lemma timesZero : forall a, a*0 = 0. + intros. + field. + Qed. +End TimesZeroParametricTestModule. + diff --git a/src/Galois/ModularBaseSystem.v b/src/Galois/ModularBaseSystem.v index 5a97d67c9..138eabd3f 100644 --- a/src/Galois/ModularBaseSystem.v +++ b/src/Galois/ModularBaseSystem.v @@ -1,7 +1,7 @@ Require Import Zpower ZArith. Require Import List. -Require Import Crypto.Galois.BaseSystem Crypto.Galois.GaloisTheory. -Require Import Util.ListUtil Util.CaseUtil Util.ZUtil. +Require Import Crypto.Galois.BaseSystem Crypto.Galois.GaloisField. +Require Import Crypto.Util.ListUtil Crypto.Util.CaseUtil Crypto.Util.ZUtil. Require Import VerdiTactics. Local Open Scope Z_scope. @@ -35,8 +35,9 @@ Module Type PseudoMersenneBaseParams (Import B:BaseCoefs) (Import M:Modulus). End PseudoMersenneBaseParams. Module Type GFrep (Import M:Modulus). - Module Import GF := GaloisTheory M. - (* TODO: could GF notation be in Galois, not GaloisTheory *) + Module Field := GaloisField M. + Import Field. + Parameter T : Type. Parameter fromGF : GF -> T. Parameter toGF : T -> GF. @@ -58,7 +59,9 @@ Module Type GFrep (Import M:Modulus). End GFrep. Module GFPseudoMersenneBase (BC:BaseCoefs) (M:Modulus) (P:PseudoMersenneBaseParams BC M) <: GFrep M. - Module Import GF := GaloisTheory M. + Module Field := GaloisField M. + Import Field. + Module EC <: BaseCoefs. Definition base := BC.base ++ (map (Z.mul (2^(P.k))) BC.base). @@ -211,7 +214,7 @@ Module GFPseudoMersenneBase (BC:BaseCoefs) (M:Modulus) (P:PseudoMersenneBasePara Definition T := B.digits. Local Hint Unfold T. - Definition toGF (us : T) : GF := GF.inject (B.decode us). + Definition toGF (us : T) : GF := inject (B.decode us). Local Hint Unfold toGF. Definition rep (us : T) (x : GF) := (length us <= length BC.base)%nat /\ toGF us = x. Local Notation "u '~=' x" := (rep u x) (at level 70). @@ -233,7 +236,7 @@ Module GFPseudoMersenneBase (BC:BaseCoefs) (M:Modulus) (P:PseudoMersenneBasePara } { unfold toGF. rewrite B.encode_rep. - rewrite GF.inject_eq; auto. + rewrite inject_eq; auto. } Qed. diff --git a/src/Rep/BinGF.v b/src/Rep/BinGF.v deleted file mode 100644 index 138277870..000000000 --- a/src/Rep/BinGF.v +++ /dev/null @@ -1,139 +0,0 @@ - -Require Import ZArith. -Require Import Bedrock.Word. -Require Import Crypto.Galois.Galois Crypto.Galois.GaloisTheory. -Require Import Crypto.Galois.ZGaloisField. -Require Import Eqdep_dec. - -Module Type BitSpec. - Parameter wordSize: nat. - Parameter numWords: nat. - - Axiom wordSize_pos : (wordSize > 0)%nat. -End BitSpec. - -Module GFBits (M: Modulus) (Spec: BitSpec). - Module Field := ZGaloisField M. - Import Field Spec. - Local Open Scope GF_scope. - Local Open Scope list. - - Definition bits {k} (x: word k) := k. - - Definition BinGF := {lst: list (word wordSize) | length lst = numWords}. - - Definition splitGt {n m} {H : (n > m)%nat} (w : word n) : word m * word (n - m). - Proof. - refine (let w' := match _ : (n = m + (n - m))%nat in _ = N return word N with - | eq_refl => w - end in - (split1 m (n - m) w', split2 m (n - m) w')); - abstract omega. - Defined. - - Fixpoint copies {A} (x : A) (n : nat) : list A := - match n with - | O => nil - | S n' => x :: copies x n' - end. - - Definition splitWords' : forall (len : nat) {sz: nat} (x: word sz), list (word wordSize). - Proof. - refine (fix splitWords' (len : nat) {sz : nat} (w : word sz) {struct len} : list (word wordSize) := - match len with - | O => nil - | S len' => - if gt_dec sz wordSize - then let (w1, w2) := splitGt w in - w1 :: splitWords' len' w2 - else match _ in _ = N return list (word N) with - | eq_refl => zext w (wordSize - sz) :: copies (wzero _) len' - end - end)%nat; clear splitWords'; abstract omega. - Defined. - - Lemma length_cast : forall A (F : A -> Type) x1 x2 (pf : x1 = x2) x xs, - length (match pf in _ = X return list (F X) with - | eq_refl => x :: xs - end) = S (length xs). - Proof. - destruct pf; auto. - Qed. - - Lemma length_copies : forall A (x : A) n, length (copies x n) = n. - Proof. - induction n; simpl; auto. - Qed. - - Hint Rewrite length_cast length_copies. - - Lemma length_splitWords' : forall len sz (w : word sz), length (splitWords' len w) = len. - Proof. - induction len; simpl; intuition; - match goal with - | [ |- context[match ?E with _ => _ end] ] => destruct E - end; simpl; try rewrite IHlen; autorewrite with core; reflexivity. - Qed. - - Definition splitWords {sz} (len: nat) (x: word sz): - {x: list (word wordSize) | length x = len}. - Proof. - exists (splitWords' len x); apply length_splitWords'. - Defined. - - Definition splitGF (x: GF) := - splitWords numWords (NToWord (numWords * wordSize)%nat (Z.to_N (proj1_sig x))). - - Fixpoint combineAll' (b: list (word wordSize)): word (wordSize * (length b)). - induction b. - - - simpl. - replace (wordSize * 0)%nat with 0%nat; intuition. - exact (natToWord 0 0). - - - replace (wordSize * length (a :: b))%nat - with (wordSize + wordSize * length b)%nat. - + exact (combine a IHb). - + simpl; rewrite mult_succ_r; intuition. - Defined. - - Definition combineAll (b: BinGF): GF := - inject (Z.of_N (wordToN (combineAll' (proj1_sig b)))). - - Definition binEquiv a b := combineAll a = combineAll b. - - Lemma combine_split: - forall (x: GF) (len: nat), - combineAll (splitGF x) = x. - Admitted. - - Record unaryOp: Set := mkUnary { - f : GF -> GF; - binF : BinGF -> BinGF; - - unaryCompat : forall (a b: GF), - a = b -> f a = f b; - - unaryBinCompat : forall (a b: BinGF), - binEquiv a b -> binEquiv (binF a) (binF b); - - unaryCorrect: forall (a: GF), - f a = combineAll (binF (splitGF a)) - }. - - Record binaryOp: Set := mkBinary { - g : GF -> GF -> GF; - binG : BinGF -> BinGF -> BinGF; - - binaryCompat : forall (a b c d: GF), - a = b -> c = d -> g a c = g b d; - - binaryBinCompat : forall (a b c d: BinGF), - binEquiv a b -> binEquiv c d -> - binEquiv (binG a c) (binG b d); - - binaryCorrect: forall (a b: GF), - g a b = combineAll (binG (splitGF a) (splitGF b)) - }. - -End GFBits. diff --git a/src/Rep/ECRep.v b/src/Rep/ECRep.v index b42e1e067..60481fe72 100644 --- a/src/Rep/ECRep.v +++ b/src/Rep/ECRep.v @@ -1,18 +1,16 @@ -Require Export Crypto.Galois.Galois Crypto.Galois.GaloisTheory. -Require Import Crypto.Galois.AbstractGaloisField. +Require Export Crypto.Galois.GaloisField. Module ECRep (M: Modulus). - Module G := Galois M. - Module F := AbstractGaloisField M. - Import M G F. + Module F := GaloisField M. + Import F. Local Open Scope GF_scope. - Definition ECSig : ADTSig := + (* Definition ECSig : ADTSig := ADTsignature { Constructor "FromTwistedXY" : GF x GF -> rep, Method "Add" : rep x rep -> rep, - }. + }.*) End ECRep. diff --git a/src/Rep/GaloisRep.v b/src/Rep/GaloisRep.v index 02844ea7c..bfd09acfd 100644 --- a/src/Rep/GaloisRep.v +++ b/src/Rep/GaloisRep.v @@ -1,14 +1,14 @@ Require Export Crypto.Galois.Galois Crypto.Galois.GaloisTheory. -Require Import Crypto.Galois.AbstractGaloisField. +Require Import Crypto.Galois.GaloisField. Module GaloisRep (M: Modulus). Module G := Galois M. - Module F := AbstractGaloisField M. + Module F := GaloisField M. Import M G F. Local Open Scope GF_scope. - Definition GFSig : ADTSig := + (* Definition GFSig : ADTSig := ADTsignature { Constructor "FromGF" : GF -> rep, @@ -22,5 +22,5 @@ Module GaloisRep (M: Modulus). : rep x rep -> rep, Method "Div" : rep x rep -> rep - }. + }. *) End GaloisRep. diff --git a/src/Specific/EdDSA25519.v b/src/Specific/EdDSA25519.v index f5546f3c8..194f94385 100644 --- a/src/Specific/EdDSA25519.v +++ b/src/Specific/EdDSA25519.v @@ -1,6 +1,6 @@ Require Import ZArith.ZArith Zpower ZArith Znumtheory. Require Import NPeano. -Require Import Galois.EdDSA Galois GaloisTheory. +Require Import Crypto.Galois.EdDSA Crypto.Galois.GaloisField. Require Import Crypto.Curves.PointFormats. Require Import Crypto.Util.NatUtil Crypto.Util.ZUtil Crypto.Util.NumTheoryUtil. Require Import Bedrock.Word. @@ -65,7 +65,8 @@ Module EdDSA25519_Params <: EdDSAParams. unfold n, b; omega. Qed. - Module Import GFDefs := GaloisDefs Modulus_q. + Module GFDefs := GaloisField Modulus_q. + Import GFDefs. Local Open Scope GF_scope. Definition a := GFopp 1%GF. @@ -105,7 +106,7 @@ Module EdDSA25519_Params <: EdDSAParams. reflexivity. Qed. - Lemma a_square : exists x, (x * x = a)%GF. + Lemma a_square_old : exists x, (x * x = a)%GF. Proof. intros. pose proof (minus1_square_1mod4 q (proj2_sig q) q_1mod4). @@ -119,15 +120,20 @@ Module EdDSA25519_Params <: EdDSAParams. (* TODO *) Parameter d : GF. + Parameter sqrt_a : GF. Axiom d_nonsquare : forall x, x^2 <> d. + Axiom a_square: (sqrt_a^2 = a)%GF. + Axiom char_gt_2: (1+1 <> 0)%GF. Module CurveParameters <: TwistedEdwardsParams Modulus_q. Module GFDefs := GFDefs. Definition a : GF := a. + Definition sqrt_a := sqrt_a. Definition a_nonzero := a_nonzero. Definition a_square := a_square. Definition d := d. Definition d_nonsquare := d_nonsquare. + Definition char_gt_2 := char_gt_2. End CurveParameters. Module Facts := CompleteTwistedEdwardsFacts Modulus_q CurveParameters. Module Import Curve := Facts.Curve. diff --git a/src/Specific/GF25519.v b/src/Specific/GF25519.v index 51f1b14c8..4b06e5230 100644 --- a/src/Specific/GF25519.v +++ b/src/Specific/GF25519.v @@ -139,7 +139,7 @@ end. Section GF25519Base25Point5Formula. Import GF25519Base25Point5. - Import GF. + Import Field. Hint Rewrite Z.mul_0_l |