aboutsummaryrefslogtreecommitdiff
path: root/src/Util/NUtil.v
diff options
context:
space:
mode:
authorGravatar jadep <jade.philipoom@gmail.com>2017-02-13 13:07:18 -0500
committerGravatar Andres Erbsen <andreser@mit.edu>2017-02-22 21:45:56 -0500
commit305253c724b263476e0aaf0359e5f9ec83211be6 (patch)
tree32548890a9a03f8acad62f23b62bea5d1a1dccbb /src/Util/NUtil.v
parent5263553bcab671860ac207e9d101332a4397268f (diff)
Moved N lemmas from Ed25519 and IterAssocOp into new NUtil file
Diffstat (limited to 'src/Util/NUtil.v')
-rw-r--r--src/Util/NUtil.v106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/Util/NUtil.v b/src/Util/NUtil.v
new file mode 100644
index 000000000..309272a90
--- /dev/null
+++ b/src/Util/NUtil.v
@@ -0,0 +1,106 @@
+Require Import Coq.NArith.NArith.
+Require Import Coq.Numbers.Natural.Peano.NPeano.
+Require Import Crypto.Util.NatUtil Crypto.Util.Decidable.
+
+Module N.
+ Lemma size_le a b : (a <= b -> N.size a <= N.size b)%N.
+ Proof.
+ destruct (dec (a=0)%N), (dec (b=0)%N); subst; auto using N.le_0_l.
+ { destruct a; auto. }
+ { rewrite !N.size_log2 by assumption.
+ rewrite <-N.succ_le_mono.
+ apply N.log2_le_mono. }
+ Qed.
+
+ Lemma le_to_nat a b : (a <= b)%N <-> (N.to_nat a <= N.to_nat b)%nat.
+ Proof.
+ rewrite <-N.lt_succ_r.
+ rewrite <-Nat.lt_succ_r.
+ rewrite <-Nnat.N2Nat.inj_succ.
+ rewrite <-NatUtil.Nat2N_inj_lt.
+ rewrite !Nnat.N2Nat.id.
+ reflexivity.
+ Qed.
+
+ Lemma size_nat_equiv : forall n, N.size_nat n = N.to_nat (N.size n).
+ Proof.
+ destruct n; auto; simpl; induction p; simpl; auto; rewrite IHp, Pnat.Pos2Nat.inj_succ; reflexivity.
+ Qed.
+
+ Lemma size_nat_le a b : (a <= b)%N -> (N.size_nat a <= N.size_nat b)%nat.
+ Proof.
+ rewrite !size_nat_equiv.
+ rewrite <-le_to_nat.
+ apply size_le.
+ Qed.
+
+ Lemma shiftr_size : forall n bound, N.size_nat n <= bound ->
+ N.shiftr_nat n bound = 0%N.
+ Proof.
+ intros.
+ rewrite <- (Nat2N.id bound).
+ rewrite Nshiftr_nat_equiv.
+ destruct (N.eq_dec n 0); subst; [apply N.shiftr_0_l|].
+ apply N.shiftr_eq_0.
+ rewrite size_nat_equiv in *.
+ rewrite N.size_log2 in * by auto.
+ apply N.le_succ_l.
+ rewrite <- N.compare_le_iff.
+ rewrite N2Nat.inj_compare.
+ rewrite <- Compare_dec.nat_compare_le.
+ rewrite Nat2N.id.
+ auto.
+ Qed.
+
+ Hint Rewrite
+ N.succ_double_spec
+ N.add_1_r
+ Nat2N.inj_succ
+ Nat2N.inj_mul
+ N2Nat.id: N_nat_conv
+ .
+
+ Lemma succ_double_to_nat : forall n,
+ N.succ_double n = N.of_nat (S (2 * N.to_nat n)).
+ Proof.
+ intros.
+ replace 2 with (N.to_nat 2) by auto.
+ autorewrite with N_nat_conv.
+ reflexivity.
+ Qed.
+
+ Lemma double_to_nat : forall n,
+ N.double n = N.of_nat (2 * N.to_nat n).
+ Proof.
+ intros.
+ replace 2 with (N.to_nat 2) by auto.
+ autorewrite with N_nat_conv.
+ reflexivity.
+ Qed.
+
+ Lemma shiftr_succ : forall n i,
+ N.to_nat (N.shiftr_nat n i) =
+ if N.testbit_nat n i
+ then S (2 * N.to_nat (N.shiftr_nat n (S i)))
+ else (2 * N.to_nat (N.shiftr_nat n (S i))).
+ Proof.
+ intros.
+ rewrite Nshiftr_nat_S.
+ case_eq (N.testbit_nat n i); intro testbit_i;
+ pose proof (Nshiftr_nat_spec n i 0) as shiftr_n_odd;
+ rewrite Nbit0_correct in shiftr_n_odd; simpl in shiftr_n_odd;
+ rewrite testbit_i in shiftr_n_odd.
+ + pose proof (Ndiv2_double_plus_one (N.shiftr_nat n i) shiftr_n_odd) as Nsucc_double_shift.
+ rewrite succ_double_to_nat in Nsucc_double_shift.
+ apply Nat2N.inj.
+ rewrite Nsucc_double_shift.
+ apply N2Nat.id.
+ + pose proof (Ndiv2_double (N.shiftr_nat n i) shiftr_n_odd) as Nsucc_double_shift.
+ rewrite double_to_nat in Nsucc_double_shift.
+ apply Nat2N.inj.
+ rewrite Nsucc_double_shift.
+ apply N2Nat.id.
+ Qed.
+
+
+End N.