https://github.com/project-everest/hacl-star
Raw File
Tip revision: 182703874c37114e651bf236756713182ba2d943 authored by Jonathan Protzenko on 24 May 2021, 17:00:19 UTC
Merge branch 'master' into son_ibmz
Tip revision: 1827038
Lib.NatMod.fsti
module Lib.NatMod

open FStar.Mul

module LE = Lib.Exponentiation

#set-options "--z3rlimit 10 --fuel 0 --ifuel 0"

let mk_nat_comm_monoid : LE.comm_monoid int = {
  LE.one = 1;
  LE.mul = FStar.Mul.op_Star;
  LE.lemma_one = Math.Lemmas.mul_one_right_is_same;
  LE.lemma_mul_assoc = Math.Lemmas.paren_mul_right;
  LE.lemma_mul_comm = Math.Lemmas.swap_mul;
  }


let rec pow (x:int) (n:nat) : Tot int =
  if n = 0 then 1
  else x * pow x (n - 1)

val lemma_pow0: a:int -> Lemma (pow a 0 = 1)
val lemma_pow1: a:int -> Lemma (pow a 1 = a)
val lemma_pow_unfold: a:int -> b:pos -> Lemma (a * pow a (b - 1) == pow a b)

val lemma_pow_gt_zero: a:pos -> b:nat -> Lemma (pow a b > 0) [SMTPat (pow a b)]
val lemma_pow_ge_zero: a:nat -> b:nat -> Lemma (pow a b >= 0) [SMTPat (pow a b)]

val lemma_pow_nat_is_pow: a:int -> b:nat ->
  Lemma (pow a b == LE.pow mk_nat_comm_monoid a b)

val lemma_pow_add: x:int -> n:nat -> m:nat -> Lemma (pow x n * pow x m = pow x (n + m))

val lemma_pow_mul: x:int -> n:nat -> m:nat -> Lemma (pow (pow x n) m = pow x (n * m))

val lemma_pow_double: a:int -> b:nat -> Lemma (pow (a * a) b == pow a (b + b))

val lemma_pow_mul_base: a:int -> b:int -> n:nat -> Lemma (pow a n * pow b n == pow (a * b) n)

val lemma_pow_mod_base: a:int -> b:nat -> n:pos -> Lemma (pow a b % n == pow (a % n) b % n)



let nat_mod (m:pos) = n:nat{n < m}

let one_mod (#m:pos) : nat_mod m = 1 % m
let mul_mod (#m:pos) (a:nat_mod m) (b:nat_mod m) : nat_mod m = a * b % m

val lemma_one_mod: #m:pos -> a:nat_mod m -> Lemma (mul_mod a one_mod == a)

val lemma_mul_mod_assoc: #m:pos -> a:nat_mod m -> b:nat_mod m -> c:nat_mod m ->
  Lemma (mul_mod (mul_mod a b) c == mul_mod a (mul_mod b c))

val lemma_mul_mod_comm: #m:pos -> a:nat_mod m -> b:nat_mod m ->
  Lemma (mul_mod a b == mul_mod b a)

let mk_nat_mod_comm_monoid (m:pos) : LE.comm_monoid (nat_mod m) = {
  LE.one = one_mod;
  LE.mul = mul_mod;
  LE.lemma_one = lemma_one_mod;
  LE.lemma_mul_assoc = lemma_mul_mod_assoc;
  LE.lemma_mul_comm = lemma_mul_mod_comm;
  }

val pow_mod: #m:pos{1 < m} -> a:nat_mod m -> b:nat -> nat_mod m

val lemma_pow_mod: #m:pos{1 < m} -> a:nat_mod m -> b:nat -> Lemma (pow a b % m == pow_mod #m a b)

val lemma_pow_nat_mod_is_pow: #n:pos{1 < n} -> a:nat_mod n -> b:nat ->
  Lemma (pow a b % n == LE.pow (mk_nat_mod_comm_monoid n) a b)
back to top