@@ -21,6 +21,7 @@ From coqutil.Tactics Require Import Tactics letexists eabstract rdelta reference
2121Require Import coqutil.Word.Bitwidth32.
2222Require Import coqutil.Word.Bitwidth.
2323Require Import coqutil.Word.Interface.
24+ Require Import coqutil.Word.Naive.
2425From Coq Require Import Init.Byte.
2526From Coq Require Import List.
2627From Coq Require Import String.
@@ -76,29 +77,40 @@ Definition add_precomputed := func! (ox, oy, oz, ota, otb, X1, Y1, Z1, Ta1, Tb1,
7677 fe25519_mul(oz, F, G)
7778}.
7879
80+ (* TODO can I pull those together somehow? *)
81+ Definition felem_size_term := Eval hnf in felem_size_in_bytes.
82+ (* Felem size in bytes in computed form. *)
83+ Definition felem_size := Eval compute in felem_size_term.
84+
85+ (* TODO how do we call these points? I call them normal points in my head :D *)
86+ Notation "A .x" := (expr.op Syntax.bopname.add A (0*felem_size)) (in custom bedrock_expr at level 3, left associativity).
87+ Notation "A .y" := (expr.op Syntax.bopname.add A (1*felem_size)) (in custom bedrock_expr at level 3, left associativity).
88+ Notation "A .z" := (expr.op Syntax.bopname.add A (2*felem_size)) (in custom bedrock_expr at level 3, left associativity).
89+ Notation "A .ta" := (expr.op Syntax.bopname.add A (3*felem_size)) (in custom bedrock_expr at level 3, left associativity).
90+ Notation "A .tb" := (expr.op Syntax.bopname.add A (4*felem_size)) (in custom bedrock_expr at level 3, left associativity).
91+
7992(* Equivalent of m1double in src/Curves/Edwards/XYZT/Basic.v *)
80- (* Note: Ta/Tb are unused, but leaving in place in case we want to switch to a point struct in the future *)
81- Definition double := func! (ox, oy, oz, ota, otb, X, Y, Z, Ta, Tb) {
82- stackalloc 40 as trX;
83- fe25519_square(trX, X);
84- stackalloc 40 as trZ;
85- fe25519_square(trZ, Y);
86- stackalloc 40 as t0;
87- fe25519_square(t0, Z);
88- stackalloc 40 as trT;
93+ Definition double := func! (p_out, p_a) {
94+ stackalloc felem_size as trX;
95+ fe25519_square(trX, p_a.x);
96+ stackalloc felem_size as trZ;
97+ fe25519_square(trZ, p_a.y);
98+ stackalloc felem_size as t0;
99+ fe25519_square(t0, p_a.z);
100+ stackalloc felem_size as trT;
89101 fe25519_carry_add(trT, t0, t0);
90- stackalloc 40 as rY;
91- fe25519_add(rY, X, Y );
102+ stackalloc felem_size as rY;
103+ fe25519_add(rY, p_a.x, p_a.y );
92104 fe25519_square(t0, rY);
93- fe25519_carry_add(otb , trZ, trX);
94- stackalloc 40 as cZ;
105+ fe25519_carry_add(p_out.tb , trZ, trX);
106+ stackalloc felem_size as cZ;
95107 fe25519_carry_sub(cZ, trZ, trX);
96- fe25519_sub(ota , t0, otb );
97- stackalloc 40 as cT;
108+ fe25519_sub(p_out.ta , t0, p_out.tb );
109+ stackalloc felem_size as cT;
98110 fe25519_sub(cT, trT, cZ);
99- fe25519_mul(ox, ota , cT);
100- fe25519_mul(oy, otb , cZ);
101- fe25519_mul(oz , cZ, cT)
111+ fe25519_mul(p_out.x, p_out.ta , cT);
112+ fe25519_mul(p_out.y, p_out.tb , cZ);
113+ fe25519_mul(p_out.z , cZ, cT)
102114}.
103115
104116(* Converting a normal point to a cached point to prepare it for readdition. *)
@@ -148,13 +160,12 @@ Section WithParameters.
148160 Context {a_eq_minus1:a = F.opp F.one} {twice_d} {k_eq_2d:twice_d = (F.add d d)} {nonzero_d: d<>F.zero}.
149161
150162Local Notation "m =* P" := ((P%sep) m) (at level 70, only parsing).
151- Local Notation "xs $@ a" := (Array.array ptsto (word.of_Z 1) a xs) (at level 10, format "xs $@ a").
152163
153164Local Notation FElem := (FElem(FieldRepresentation:=frep25519)).
154165Local Notation bounded_by := (bounded_by(FieldRepresentation:=frep25519)).
155166Local Notation word := (Naive.word 32).
156167Local Notation felem := (felem(FieldRepresentation:=frep25519)).
157- Local Notation point := (point(Fzero:=F.zero)(Fadd:=F.add)(Fmul:=F.mul)(a:=a)(d:=d)).
168+ Local Notation point := (point(Feq:=Logic.eq)( Fzero:=F.zero)(Fadd:=F.add)(Fmul:=F.mul)(a:=a)(d:=d)).
158169Local Notation cached := (cached(Fzero:=F.zero)(Fadd:=F.add)(Fmul:=F.mul)(a:=a)(d:=d)).
159170Local Notation coordinates := (coordinates(Feq:=Logic.eq)).
160171Local Notation m1double :=
@@ -216,28 +227,34 @@ Global Instance spec_of_add_precomputed : spec_of "add_precomputed" :=
216227 bounded_by loose_bounds otb' /\
217228 m' =* (FElem X1K X1) * (FElem Y1K Y1) * (FElem Z1K Z1) * (FElem Ta1K Ta1) * (FElem Tb1K Tb1) * (FElem half_ypxK half_ypx) * (FElem half_ymxK half_ymx) * (FElem xydK xyd) * (FElem oxK ox') * (FElem oyK oy') * (FElem ozK oz') * (FElem otaK ota') * (FElem otbK otb') * R }.
218229
230+ Definition coords_bounds := (Field.bounds * Field .bounds * Field .bounds * Field .bounds * Field .bounds)%type.
231+ (* TODO find a good name for this construct. *)
232+ Definition bounded_coords := (felem * felem * felem * felem * felem)%type.
233+ Definition feval_coords '(x, y, z, ta, tb) := (feval x, feval y, feval z, feval ta, feval tb).
234+
235+ Definition coords_bounded_by (bounds : coords_bounds) '(x,y,z,ta,tb) : Prop :=
236+ let '(bounds_x, bounds_y, bounds_z, bounds_ta, bounds_tb) := bounds in
237+ bounded_by bounds_x x /\ bounded_by bounds_y y /\ bounded_by bounds_z z /\ bounded_by bounds_ta ta /\ bounded_by bounds_tb tb.
238+
239+ Local Notation "p .+ n" := (word.add p (word.of_Z n)) (at level 50, format "p .+ n", left associativity).
240+ Local Notation "c $@ p" := (let '(x,y,z,ta,tb) := c in sep (sep (sep (sep (FElem (p .+ 0) x) (FElem (p .+ 40) y)) (FElem (p .+ 80) z)) (FElem (p .+ 120) ta)) (FElem (p .+ 160) tb)) (at level 10, format "c $@ p").
241+
242+
219243Global Instance spec_of_double : spec_of "double" :=
220244 fnspec! "double"
221- (oxK oyK ozK otaK otbK XK YK ZK TaK TbK : word) /
222- (ox oy oz ota otb X Y Z Ta Tb : felem) (p : point) (R : _ -> Prop),
223- { requires t m :=
224- coordinates p = ((feval X), (feval Y), (feval Z), (feval Ta), (feval Tb)) /\
225- bounded_by tight_bounds X /\
226- bounded_by tight_bounds Y /\
227- bounded_by loose_bounds Z /\
228- bounded_by loose_bounds Ta /\
229- bounded_by loose_bounds Tb /\
230- m =* (FElem XK X) * (FElem YK Y) * (FElem ZK Z) * (FElem TaK Ta) * (FElem TbK Tb) * (FElem oxK ox) * (FElem oyK oy) * (FElem ozK oz) * (FElem otaK ota) * (FElem otbK otb) * R;
231- ensures t' m' :=
245+ (p_out p_a : word) /
246+ (p : point) (a anything: bounded_coords) (R : _ -> Prop), {
247+ requires t m :=
248+ coords_bounded_by (tight_bounds, tight_bounds, loose_bounds, loose_bounds, loose_bounds) a /\
249+ feval_coords a = coordinates p /\
250+ m =* anything $@ p_out * a $@ p_a * R;
251+ ensures t' m' :=
232252 t = t' /\
233- exists ox' oy' oz' ota' otb',
234- ((feval ox'), (feval oy'), (feval oz'), (feval ota'), (feval otb')) = coordinates (@m1double p) /\
235- bounded_by tight_bounds ox' /\
236- bounded_by tight_bounds oy' /\
237- bounded_by tight_bounds oz' /\
238- bounded_by loose_bounds ota' /\ (* could be tight_bounds if we need it, but I don't think we do *)
239- bounded_by tight_bounds otb' /\
240- m' =* (FElem XK X) * (FElem YK Y) * (FElem ZK Z) * (FElem TaK Ta) * (FElem TbK Tb) * (FElem oxK ox') * (FElem oyK oy') * (FElem ozK oz') * (FElem otaK ota') * (FElem otbK otb') * R }.
253+ exists a_double : bounded_coords,
254+ coordinates (@m1double p) = feval_coords a_double /\
255+ coords_bounded_by (tight_bounds, tight_bounds, tight_bounds, loose_bounds, tight_bounds) a_double /\
256+ m' =* a_double $@ p_out * a $@ p_a * R
257+ }.
241258
242259Global Instance spec_of_to_cached: spec_of "to_cached" :=
243260 fnspec! "to_cached"
@@ -309,10 +326,13 @@ Local Arguments word.rep : simpl never.
309326Local Arguments word.wrap : simpl never.
310327Local Arguments word.unsigned : simpl never.
311328Local Arguments word.of_Z : simpl never.
329+ Local Arguments word.add : simpl never.
330+
331+ Local Arguments feval : simpl never.
312332
313333Local Ltac cbv_bounds H :=
314- cbv [un_xbounds bin_xbounds bin_ybounds un_square bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_outbounds bin_outbounds] in H;
315- cbv [un_xbounds bin_xbounds bin_ybounds un_square bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_outbounds bin_outbounds].
334+ cbv [coords_bounded_by un_xbounds bin_xbounds bin_ybounds un_square bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_outbounds bin_outbounds] in H;
335+ cbv [coords_bounded_by un_xbounds bin_xbounds bin_ybounds un_square bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_outbounds bin_outbounds].
316336
317337Local Ltac solve_bounds :=
318338 repeat match goal with
@@ -376,22 +396,6 @@ Proof.
376396 reflexivity. (* ...and completes immediately *)
377397Qed .
378398
379- Lemma to_cached_ok: program_logic_goal_for_function! to_cached.
380- Proof .
381- repeat single_step. repeat straightline.
382-
383- exists x1, x3, z, x5; ssplit; try solve_bounds; try solve_mem.
384-
385- destruct p.
386- cbv [bin_model bin_mul bin_add bin_carry_add bin_sub coordinates proj1_sig] in *.
387- cbv match beta delta [m1_prep cached_coordinates proj1_sig].
388- rewrite H31, H28, H26, H22, H20, H16.
389- simpl. rewrite H6. auto.
390-
391- (* Without this, resolution of cbv stalls out Qed . *)
392- Strategy -1000 [un_xbounds bin_xbounds bin_ybounds un_square bin_model cached_coordinates proj1_sig bin_mul bin_add bin_carry_add bin_sub un_outbounds bin_outbounds].
393- Qed .
394-
395399Lemma add_precomputed_ok : program_logic_goal_for_function! add_precomputed.
396400Proof .
397401 (* Without this, resolution of cbv stalls out Qed . *)
@@ -446,53 +450,61 @@ Proof.
446450 (* Without this, resolution of cbv stalls out Qed . *)
447451 Strategy -1000 [un_xbounds bin_xbounds bin_ybounds un_square bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_outbounds bin_outbounds].
448452
449- (* Unwrap each call in the program. *)
450- (* Each binop produces 2 memory goals on the inputs, 2 bounds goals on the inputs, and 1 memory goal on the output. *)
451- single_step. (* fe25519_square(trX, X) *)
452- single_step. (* fe25519_square(trZ, Y) *)
453- single_step. (* fe25519_square(t0, Z) *)
454- single_step. (* fe25519_carry_add(trT, t0, t0) *)
455- single_step. (* fe25519_add(rY, X, Y) *)
456- single_step. (* fe25519_square(t0, rY) *)
457- single_step. (* fe25519_carry_add(otb, trZ, trX) *)
458- single_step. (* fe25519_carry_sub(cZ, trZ, trX) *)
459- single_step. (* fe25519_sub(ota, t0, otb) *)
460- single_step. (* fe25519_sub(cT, trT, cZ) *)
461- single_step. (* fe25519_mul(ox, ota, cT) *)
462- single_step. (* fe25519_mul(oy, otb, cZ) *)
463- single_step. (* fe25519_mul(oz, cZ, cT) *)
453+ straightline.
454+ destruct a0 as ((((fx, fy), fz), fta), ftb).
455+ destruct p as (((((x, y), z), ta), tb), HP).
456+ destruct anything as ((((ax, ay), az), ata), atb).
457+ cbv beta match delta [feval_coords coords_bounded_by coordinates proj1_sig] in *.
458+ repeat straightline.
459+ inversion H13.
460+
461+ repeat single_step.
464462
465463 (* Solve the postconditions *)
466464 repeat straightline.
467- (* Rewrites the FElems for the stack (in H87) to be about bytes instead *)
468- cbv [FElem] in *.
469- (* Prevent output from being rewritten by seprewrite_in *)
470- remember (Bignum.Bignum felem_size_in_words ozK _) as Pz in H87.
471- remember (Bignum.Bignum felem_size_in_words oyK _) as Py in H87.
472- remember (Bignum.Bignum felem_size_in_words oxK _) as Px in H87.
473- remember (Bignum.Bignum felem_size_in_words otaK _) as Pta in H87.
474- remember (Bignum.Bignum felem_size_in_words otbK _) as Ptb in H87.
475- do 7 (seprewrite_in @Bignum.Bignum_to_bytes H87).
476- subst Pz Py Px Pta Ptb.
477- extract_ex1_and_emp_in H87.
465+
466+ (* Now we need to convert scalar to ptsto, because straightline_dealloc can't handle scalar yet. *)
467+ cbv [FElem] in *.
468+ (* Prevent output from being rewritten by seprewrite_in *)
469+ remember (Bignum.Bignum felem_size_in_words (p_out.+80) x12) as Pz in H92.
470+ remember (Bignum.Bignum felem_size_in_words (p_out.+40) x11) as Py in H92.
471+ remember (Bignum.Bignum felem_size_in_words (p_out.+0) x10) as Px in H92.
472+ remember (Bignum.Bignum felem_size_in_words (p_out.+120) x8) as Pta in H92.
473+ remember (Bignum.Bignum felem_size_in_words (p_out.+160) x6) as Ptb in H92.
474+ do 7 (seprewrite_in @Bignum.Bignum_to_bytes H92).
475+ subst Pz Py Px Pta Ptb.
476+ extract_ex1_and_emp_in H92.
478477
479478 (* Solve stack/memory stuff *)
480479 repeat straightline.
481480
482481 (* Post-conditions *)
483- exists x9, x10,x11,x7,x5 ; ssplit. 2,3,4,5,6:solve_bounds.
482+ exists ( x10,x11,x12,x8,x6) ; ssplit. 2,3,4,5,6:solve_bounds.
484483 { (* Correctness: result matches Gallina *)
485484 cbv [bin_model bin_mul bin_add bin_carry_add bin_sub bin_carry_sub un_model un_square] in *.
486- cbv match beta delta [m1double coordinates proj1_sig].
487- destruct p. cbv [coordinates proj1_sig] in H12.
488- rewrite H12.
485+ cbv match zeta beta delta [m1double coordinates proj1_sig].
489486 rewrite F.pow_2_r in *.
490487 congruence.
491488 }
492489 (* Safety: memory is what it should be *)
493490 ecancel_assumption.
494491Qed .
495492
493+ Lemma to_cached_ok: program_logic_goal_for_function! to_cached.
494+ Proof .
495+ repeat single_step. repeat straightline.
496+
497+ exists x1, x3, z, x5; ssplit; try solve_bounds; try solve_mem.
498+
499+ destruct p.
500+ cbv [bin_model bin_mul bin_add bin_carry_add bin_sub coordinates proj1_sig] in *.
501+ cbv match beta delta [m1_prep cached_coordinates proj1_sig].
502+ rewrite H31, H28, H26, H22, H20, H16.
503+ simpl. rewrite H6. auto.
504+
505+ (* Without this, resolution of cbv stalls out Qed . *)
506+ Strategy -1000 [un_xbounds bin_xbounds bin_ybounds un_square bin_model cached_coordinates proj1_sig bin_mul bin_add bin_carry_add bin_sub un_outbounds bin_outbounds].
507+ Qed .
496508
497509Lemma readd_ok : program_logic_goal_for_function! readd.
498510Proof .
0 commit comments