@@ -55,6 +55,10 @@ Class word_by_word_Montgomery_ops
55
55
(WordByWordMontgomery.square m width)
56
56
Field .square
57
57
list_unop_insizes list_unop_outsizes (list_unop_inlengths n);
58
+ felem_copy_op :
59
+ computed_op
60
+ (WordByWordMontgomery.copy m width) Field .felem_copy
61
+ list_unop_insizes list_unop_outsizes (list_unop_inlengths n);
58
62
from_bytes_op :
59
63
computed_op
60
64
(WordByWordMontgomery.from_bytes m width)
@@ -165,13 +169,14 @@ Section WordByWordMontgomery.
165
169
(to_mont : string)
166
170
(ops : word_by_word_Montgomery_ops n m)
167
171
mul_func add_func sub_func opp_func square_func
168
- from_bytes_func to_bytes_func
172
+ felem_copy_func from_bytes_func to_bytes_func
169
173
from_mont_func to_mont_func select_znz_func
170
174
(mul_func_eq : mul_func = b2_func mul_op)
171
175
(add_func_eq : add_func = b2_func add_op)
172
176
(sub_func_eq : sub_func = b2_func sub_op)
173
177
(opp_func_eq : opp_func = b2_func opp_op)
174
178
(square_func_eq : square_func = b2_func square_op)
179
+ (felem_copy_func_eq : felem_copy_func = b2_func felem_copy_op)
175
180
(from_bytes_func_eq : from_bytes_func = b2_func from_bytes_op)
176
181
(to_bytes_func_eq : to_bytes_func = b2_func to_bytes_op)
177
182
(from_mont_func_eq : from_mont_func = b2_func from_mont_op)
@@ -492,6 +497,41 @@ Qed.
492
497
intros. apply Hcorrect; auto. }
493
498
Qed .
494
499
500
+ Lemma list_Z_bounded_by_unsigned (xs : list (@Interface.word.rep _ word)) :
501
+ list_Z_bounded_by
502
+ (Primitives.saturated_bounds (List.length xs) width)
503
+ (map Interface.word.unsigned xs).
504
+ Proof using parameters_sentinel ok.
505
+ induction xs; cbn; [reflexivity|].
506
+ eapply list_Z_bounded_by_cons; split; [|assumption].
507
+ eapply Bool.andb_true_iff; split; eapply Z.leb_le;
508
+ cbv [Primitives.word_bound]; cbn.
509
+ { eapply Properties.word.unsigned_range. }
510
+ { eapply Le.Z.le_sub_1_iff, Properties.word.unsigned_range. }
511
+ Qed .
512
+
513
+ Lemma felem_copy_func_correct :
514
+ valid_func (res felem_copy_op _) ->
515
+ forall functions,
516
+ Interface.map.get functions Field .felem_copy = Some felem_copy_func ->
517
+ (@spec_of_felem_copy _ _ _ _ _ _ _ field_representation_raw) functions.
518
+ Proof using M_eq check_args_ok felem_copy_func_eq ok.
519
+ cbv [spec_of_felem_copy]. rewrite felem_copy_func_eq. intros.
520
+ pose proof copy_correct
521
+ _ _ _ ltac:(eassumption) _ (res_eq felem_copy_op)
522
+ as Hcorrect.
523
+
524
+ eapply felem_copy_correct; [ .. | eassumption | eassumption ];
525
+ repeat handle_side_conditions; [ | ]; intros.
526
+ { (* output *value* is correct *)
527
+ unshelve erewrite (proj1 (Hcorrect _ _)); cycle 1.
528
+ { rewrite map_map, List.map_ext_id; trivial; intros.
529
+ rewrite ?Word.Interface.word.of_Z_unsigned; trivial. }
530
+ { rewrite <- H2. exact (list_Z_bounded_by_unsigned x0). } }
531
+ { (* output *bounds* are correct *)
532
+ intros. apply Hcorrect; auto. }
533
+ Qed .
534
+
495
535
Lemma from_bytes_func_correct :
496
536
valid_func (res from_bytes_op _) ->
497
537
forall functions,
0 commit comments