aboutsummaryrefslogtreecommitdiff
path: root/src/Spec/Encoding.v
blob: 95ac85c975c96fe1a1c097f5831cc38c906f8e15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Require Import ZArith.ZArith Zpower ZArith.
Require Import NPeano.
Require Import Crypto.ModularArithmetic.PrimeFieldTheorems Crypto.ModularArithmetic.ModularArithmeticTheorems.
Require Import Bedrock.Word.
Require Import VerdiTactics.
Require Import Crypto.Util.NatUtil.

Class Encoding (T B:Type) := {
  enc : T -> B ;
  dec : B -> option T ;
  encoding_valid : forall x, dec (enc x) = Some x
}.
Notation "'encoding' 'of' T 'as' B" := (Encoding T B) (at level 50).

Local Open Scope nat_scope.

Section ModularWordEncoding.
  Context {m : Z} {sz : nat} {m_pos : (0 < m)%Z} {bound_check : Z.to_nat m < 2 ^ sz}.

  Definition Fm_enc (x : F m) : word sz := natToWord sz (Z.to_nat (FieldToZ x)).

  Definition Fm_dec (x_ : word sz) : option (F m) :=
    let z := Z.of_nat (wordToNat (x_)) in
    if Z_lt_dec z m
      then Some (ZToField z)
      else None
  .

  Lemma bound_check_N : forall x : F m, (N.of_nat (Z.to_nat x) < Npow2 sz)%N.
  Proof.
    intro.
    pose proof (FieldToZ_range x m_pos) as x_range.
    rewrite <- Nnat.N2Nat.id.
    rewrite Npow2_nat.
    apply (Nat2N_inj_lt (Z.to_nat x) (pow2 sz)).
    rewrite ZUtil.Zpow_pow2.
    destruct x_range as [x_low x_high].
    apply Z2Nat.inj_lt in x_high; try omega.
    rewrite <- ZUtil.pow_Z2N_Zpow by omega.
    replace (Z.to_nat 2) with 2%nat by auto.
    omega.
  Qed.

  Lemma Fm_encoding_valid : forall x, Fm_dec (Fm_enc x) = Some x.
  Proof.
    unfold Fm_dec, Fm_enc; intros.
    pose proof (FieldToZ_range x m_pos).
    rewrite wordToNat_natToWord_idempotent by apply bound_check_N.
    rewrite Z2Nat.id by omega.
    rewrite ZToField_idempotent.
    break_if; auto; omega.
  Qed.

  Instance modular_word_encoding : encoding of F m as word sz := {
    enc := Fm_enc;
    dec := Fm_dec;
    encoding_valid := Fm_encoding_valid
  }.

End ModularWordEncoding.