@@ -6,6 +6,8 @@ Require Import Crypto.Spec.MontgomeryCurve.
6
6
Require Import Crypto.Spec.Curve25519.
7
7
Require Import bedrock2.Map.Separation.
8
8
Require Import bedrock2.Syntax.
9
+ Require Import bedrock2Examples.memmove.
10
+ Require Import bedrock2.SepAutoArray.
9
11
Require Import compiler.Pipeline.
10
12
Require Import compiler.Symbols.
11
13
Require Import compiler.MMIO.
@@ -18,6 +20,7 @@ Require Import Crypto.Bedrock.Group.ScalarMult.LadderStep.
18
20
Require Import Crypto.Bedrock.Group.ScalarMult.CSwap.
19
21
Require Import Crypto.Bedrock.Group.ScalarMult.MontgomeryLadder.
20
22
Require Import Crypto.Bedrock.End2End.X25519.Field25519.
23
+ Require Import Crypto.Bedrock.End2End.X25519.clamp.
21
24
Local Open Scope string_scope.
22
25
Import ListNotations.
23
26
@@ -32,38 +35,52 @@ Proof. vm_compute. subst; exact eq_refl. Qed.
32
35
Require Import bedrock2.NotationsCustomEntry.
33
36
34
37
Definition x25519 := func! (out, sk, pk) {
38
+ stackalloc 32 as K;
39
+ memmove(K, sk, $32);
40
+ clamp(K);
35
41
stackalloc 40 as U;
36
42
fe25519_from_bytes(U, pk);
37
43
stackalloc 40 as OUT;
38
- montladder(OUT, sk , U);
44
+ montladder(OUT, K , U);
39
45
fe25519_to_bytes(out, OUT)
40
46
}.
41
47
42
48
Definition x25519_base := func! (out, sk) {
49
+ stackalloc 32 as K;
50
+ memmove(K, sk, $32);
51
+ clamp(K);
43
52
stackalloc 40 as U;
44
53
fe25519_from_word(U, $9);
45
54
stackalloc 40 as OUT;
46
- montladder(OUT, sk , U);
55
+ montladder(OUT, K , U);
47
56
fe25519_to_bytes(out, OUT)
48
57
}.
49
58
50
59
Import LittleEndianList.
51
60
Local Coercion F.to_Z : F >-> Z.
52
61
Require Import bedrock2.WeakestPrecondition bedrock2.Semantics bedrock2.ProgramLogic.
53
62
Require Import bedrock2.Syntax bedrock2.Map.SeparationLogic.
54
- Require Import coqutil.Map.OfListWord Coq.Init.Byte coqutil.Byte.
63
+ Require Import Coq.Init.Byte coqutil.Byte.
55
64
Import ProgramLogic.Coercions .
56
65
Local Notation "m =* P" := ((P%sep) m) (at level 70, only parsing) (* experiment *) .
57
66
Local Notation "xs $@ a" := (Array.array ptsto (word.of_Z 1) a xs) (at level 10, format "xs $@ a").
58
67
68
+ Definition x25519_spec s P := le_split 32 (M.X0 (Curve25519.M.scalarmult (Curve25519.clamp (le_combine s)) P)).
69
+ Lemma length_x25519_spec s P : length (x25519_spec s P) = 32%nat. Proof . apply length_le_split. Qed .
70
+
59
71
Global Instance spec_of_x25519 : spec_of "x25519" :=
60
72
fnspec! "x25519" out sk pk / (o s p : list Byte.byte) P (R : _ -> Prop),
61
73
{ requires t m := m =* s$@sk * p$@pk * o$@out * R /\
62
74
length s = 32%nat /\ length p = 32%nat /\ length o = 32%nat /\
63
75
byte.unsigned (nth 31 p x00) <= 0x7f /\ Field .feval_bytes(field_parameters:=field_parameters) p = Curve25519.M.X0 P;
64
- ensures t' m := t=t' /\ m=* s$@sk ⋆ p$@pk ⋆ R ⋆
65
- (le_split 32 (M.X0 (Curve25519.M.scalarmult (le_combine s mod 2^255) P))$@out) }.
76
+ ensures t' m := t=t' /\ m=* s$@sk ⋆ p$@pk ⋆ R ⋆ (x25519_spec s P)$@out }.
66
77
78
+ Global Instance spec_of_x25519_base : spec_of "x25519_base" :=
79
+ fnspec! "x25519_base" out sk / (o s : list Byte.byte) (R : _ -> Prop),
80
+ { requires t m := m =* s$@sk * o$@out * R /\ length s = 32%nat /\ length o = 32%nat;
81
+ ensures t' m := t=t' /\ m=* s$@sk ⋆ R ⋆ (x25519_spec s Curve25519.M.B)$@out }.
82
+
83
+ Local Instance spec_of_memmove_array : spec_of "memmove" := spec_of_memmove_array.
67
84
Local Instance spec_of_fe25519_from_word : spec_of "fe25519_from_word" := Field.spec_of_from_word.
68
85
Local Instance spec_of_fe25519_from_bytes : spec_of "fe25519_from_bytes" := Field.spec_of_from_bytes.
69
86
Local Instance spec_of_fe25519_to_bytes : spec_of "fe25519_to_bytes" := Field.spec_of_to_bytes.
@@ -81,12 +98,16 @@ Local Arguments word.of_Z : simpl never.
81
98
Lemma x25519_ok : program_logic_goal_for_function! x25519.
82
99
Proof .
83
100
repeat straightline.
84
- seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a) H2. { transitivity 40%nat; trivial. }
101
+
102
+ straightline_call; ssplit; try ecancel_assumption; repeat straightline; try listZnWords; [].
103
+ straightline_call; ssplit; try ecancel_assumption; repeat straightline; try listZnWords; [].
104
+
105
+ seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a0) H17. { transitivity 40%nat; trivial. }
85
106
86
107
straightline_call; ssplit.
87
108
{ eexists. ecancel_assumption. }
88
109
{ cbv [Field.FElem].
89
- use_sep_assumption. cancel. cancel_seps_at_indices 0%nat 0%nat; cbn; trivial. eapply RelationClasses.reflexivity. }
110
+ use_sep_assumption. cancel. cancel_seps_at_indices 0%nat 0%nat; cbn [seps]; eapply RelationClasses.reflexivity. }
90
111
{ unfold Field.bytes_in_bounds, frep25519, field_representation, Signature.field_representation, Representation.frep.
91
112
match goal with |- ?P ?x ?z => let y := eval cbv in x in change (P y z) end; cbn.
92
113
repeat (destruct p as [|? p]; try (cbn [length] in *;discriminate); []).
@@ -100,7 +121,7 @@ Proof.
100
121
eapply byte.unsigned_range. }
101
122
repeat straightline.
102
123
103
- seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a2) H16 . { transitivity 40%nat; trivial. }
124
+ seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a2) H24 . { transitivity 40%nat; trivial. }
104
125
105
126
straightline_call; ssplit.
106
127
{ unfold FElem, Field.FElem in *; extract_ex1_and_emp_in_goal; ssplit.
@@ -109,10 +130,10 @@ Proof.
109
130
all : eauto.
110
131
{ instantiate (1:=None). exact I. } }
111
132
{ reflexivity. }
112
- { rewrite H3 . vm_compute. inversion 1. }
133
+ { rewrite ?length_le_split . vm_compute. inversion 1. }
113
134
repeat straightline.
114
135
115
- specialize (H23 P ltac:(assumption)). cbv [FElem] in H23 . extract_ex1_and_emp_in H23 .
136
+ specialize (H31 P ltac:(assumption)). cbv [FElem] in H31 . extract_ex1_and_emp_in H31 .
116
137
straightline_call; ssplit.
117
138
{ ecancel_assumption. }
118
139
{ transitivity 32%nat; auto. }
@@ -122,43 +143,46 @@ Proof.
122
143
repeat straightline.
123
144
124
145
cbv [Field.FElem] in *.
125
- seprewrite_in @Bignum.Bignum_to_bytes H26.
126
- seprewrite_in @Bignum.Bignum_to_bytes H26.
127
- extract_ex1_and_emp_in H26.
146
+ seprewrite_in @Bignum.Bignum_to_bytes H34.
147
+ seprewrite_in @Bignum.Bignum_to_bytes H34.
148
+ extract_ex1_and_emp_in H34.
149
+ pose proof length_le_split 32 (Curve25519.clamp (le_combine s)).
128
150
129
151
repeat straightline; intuition eauto.
130
- rewrite H30 in *.
131
- use_sep_assumption; cancel. reflexivity.
152
+ cbv [x25519_spec].
153
+ use_sep_assumption; cancel.
154
+ rewrite H38, le_combine_split.
155
+ do 7 Morphisms.f_equiv.
156
+ pose proof clamp_range (le_combine s).
157
+ (rewrite_strat bottomup Z.mod_small); change (Z.of_nat (Z.to_nat (Z.log2 (Z.pos order)))) with 255; try Lia.lia.
132
158
Qed .
133
159
134
- Global Instance spec_of_x25519_base : spec_of "x25519_base" :=
135
- fnspec! "x25519_base" out sk / (o s : list Byte.byte) (R : _ -> Prop),
136
- { requires t m := m =* s$@sk * o$@out * R /\ length s = 32%nat /\ length o = 32%nat;
137
- ensures t' m := t=t' /\ m=* s$@sk ⋆ R ⋆
138
- le_split 32 (M.X0 (Curve25519.M.scalarmult (le_combine s mod 2^255) Curve25519.M.B))$@out }.
139
-
140
160
Lemma x25519_base_ok : program_logic_goal_for_function! x25519_base.
141
161
Proof .
142
162
repeat straightline.
143
- seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a) H2. { transitivity 40%nat; trivial. }
163
+
164
+ straightline_call; ssplit; try ecancel_assumption; repeat straightline; try listZnWords; [].
165
+ straightline_call; ssplit; try ecancel_assumption; repeat straightline; try listZnWords; [].
166
+
167
+ seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a0) H14. { transitivity 40%nat; trivial. }
144
168
straightline_call; ssplit.
145
169
{ cbv [Field.FElem]. cbn. cbv [n]. ecancel_assumption. }
146
170
repeat straightline.
147
171
148
- seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a2) H13 . { transitivity 40%nat; trivial. }
172
+ seprewrite_in (@Bignum.Bignum_of_bytes _ _ _ _ _ _ 10 a2) H21 . { transitivity 40%nat; trivial. }
149
173
150
174
straightline_call; ssplit.
151
175
{ unfold FElem, Field.FElem in *; extract_ex1_and_emp_in_goal; ssplit.
152
176
{ use_sep_assumption. cancel; repeat ecancel_step.
153
- cancel_seps_at_indices 0%nat 0%nat; trivial. cbn; reflexivity. }
177
+ cancel_seps_at_indices 0%nat 0%nat; trivial. cbn [seps]. reflexivity. }
154
178
all : eauto.
155
179
{ instantiate (1:=None). exact I. } }
156
180
{ reflexivity. }
157
- { rewrite H3 . vm_compute. inversion 1. }
181
+ { rewrite length_le_split . vm_compute. inversion 1. }
158
182
repeat straightline.
159
183
160
- specialize (H20 Curve25519.M.B eq_refl).
161
- unfold FElem in H20 . extract_ex1_and_emp_in H20 .
184
+ specialize (H28 Curve25519.M.B eq_refl).
185
+ unfold FElem in H28 . extract_ex1_and_emp_in H28 .
162
186
straightline_call; ssplit.
163
187
{ ecancel_assumption. }
164
188
{ transitivity 32%nat; auto. }
@@ -168,13 +192,18 @@ Proof.
168
192
repeat straightline.
169
193
170
194
cbv [Field.FElem] in *.
171
- seprewrite_in @Bignum.Bignum_to_bytes H23.
172
- seprewrite_in @Bignum.Bignum_to_bytes H23.
173
- extract_ex1_and_emp_in H23.
195
+ seprewrite_in @Bignum.Bignum_to_bytes H31.
196
+ seprewrite_in @Bignum.Bignum_to_bytes H31.
197
+ extract_ex1_and_emp_in H31.
198
+ pose proof length_le_split 32 (Curve25519.clamp (le_combine s)).
174
199
175
200
repeat straightline; intuition eauto.
176
- rewrite H27 in *.
177
- use_sep_assumption; cancel. reflexivity.
201
+ cbv [x25519_spec].
202
+ use_sep_assumption; cancel.
203
+ rewrite H35, le_combine_split.
204
+ do 7 Morphisms.f_equiv.
205
+ pose proof clamp_range (le_combine s).
206
+ (rewrite_strat bottomup Z.mod_small); change (Z.of_nat (Z.to_nat (Z.log2 (Z.pos order)))) with 255; try Lia.lia.
178
207
Qed .
179
208
180
209
Require Import coqutil.Word.Naive.
@@ -197,7 +226,9 @@ Definition funcs :=
197
226
fe25519_add;
198
227
fe25519_sub;
199
228
fe25519_square;
200
- fe25519_scmula24 ].
229
+ fe25519_scmula24;
230
+ clamp;
231
+ memmove ].
201
232
202
233
Require Import bedrock2.ToCString.
203
234
Definition montladder_c_module := list_byte_of_string (ToCString.c_module funcs).
0 commit comments