https://github.com/EasyCrypt/easycrypt
Raw File
Tip revision: 374dae60b90d55b70e41805c88b33b26faaa455d authored by Pierre-Yves Strub on 12 October 2021, 13:09:21 UTC
parser: fix precedence issue
Tip revision: 374dae6
BitWord.eca
(* --------------------------------------------------------------------
 * Copyright (c) - 2012--2016 - IMDEA Software Institute
 * Copyright (c) - 2012--2018 - Inria
 * Copyright (c) - 2012--2018 - Ecole Polytechnique
 *
 * Distributed under the terms of the CeCILL-B-V1 license
 * -------------------------------------------------------------------- *)

(* -------------------------------------------------------------------- *)
require import Bool Core Int List.
require (*--*) FinType Word Ring.

pragma +implicits.

(* -------------------------------------------------------------------- *)
op n : {int | 0 < n} as gt0_n.

clone include Word with
  type Alphabet.t    <- bool,
  op   Alphabet.enum <- [true; false],
  op   Alphabet.card <- 2,
  op   n             <- n,
  op   dchar         <- false

proof Alphabet.* by case, ge0_n by apply/ltzW/gt0_n

rename [op] "oflist"  as "bits2w"
       [op] "tolist"  as "w2bits".

(* -------------------------------------------------------------------- *)
op zerow: word = offun (fun i => false).
op onew : word = offun (fun i => true ).

op (+^) (w1 w2 : word): word =
  offun (fun i => w1.[i] ^^ w2.[i]).

op andw (w1 w2:word): word =
  offun (fun i => w1.[i] /\ w2.[i]).

op oppw (w : word): word = w.

op invw (w : word): word =
  offun (fun i => !w.[i]).

(* -------------------------------------------------------------------- *)
lemma zerowE i: zerow.[i] = false.
proof. by rewrite offunifE. qed.

lemma onewE i: onew.[i] = (0 <= i < n).
proof. by rewrite offunifE; case: (_ <= _ < _)%Int. qed.

lemma xorwE w1 w2 i: (w1 +^ w2).[i] = w1.[i] ^^ w2.[i].
proof.
rewrite offunifE /= andaE eq_iff; apply/andb_idl.
by case: (0 <= i < n)=> // h; rewrite !getE h.
qed.

lemma andwE (w1 w2:word) i: (andw w1 w2).[i] = (w1.[i] /\ w2.[i]).
proof.
rewrite offunifE /= andaE eq_iff; apply/andb_idl.
by case: (0 <= i < n) => // h; rewrite !getE h.
qed.

lemma invwE (w:word) i: 0 <= i < n =>
  (invw w).[i] = !w.[i].
proof. by move=> lt_in; rewrite offunE. qed.

lemma oppwE (w:word) i: (oppw w).[i] = w.[i].
proof. by []. qed.

hint rewrite bwordE : zerowE onewE xorwE andwE invwE.

(* -------------------------------------------------------------------- *)
lemma onew_neq0: onew <> zerow.
proof. by apply/negP=> /wordP/(_ 0); rewrite !bwordE /= gt0_n. qed.

lemma xorw0: right_id zerow (+^).
proof. by move=> w; apply/wordP=> i _; rewrite !bwordE xor_false. qed.

lemma xorwA: associative (+^).
proof. by move=> w1 w2 w3; apply/wordP=> i _; rewrite !bwordE xorA. qed.

lemma xorwC: commutative (+^).
proof. by move=> w1 w2; apply/wordP=> i _; rewrite !bwordE xorC. qed.

lemma xorwK: forall x, x +^ x = zerow.
proof. by move=> w; apply/wordP=> i _; rewrite !bwordE xorK. qed.

lemma andw1: right_id onew andw.
proof. by move=> w; apply/wordP=> i h; rewrite !bwordE h. qed.

lemma andwA: associative andw.
proof. by move=> w1 w2 w3; apply/wordP=> i h; rewrite !bwordE andbA. qed.

lemma andwC: commutative andw.
proof. by move=> w1 w2; apply/wordP=> i h; rewrite !bwordE andbC. qed.

lemma andwDl: left_distributive andw (+^).
proof. move=> w1 w2 w3; apply/wordP=> i h; rewrite !bwordE smt. qed.

lemma andwK: idempotent andw.
proof. by move=> x; apply/wordP=> i h; rewrite !bwordE andbb. qed.

(* -------------------------------------------------------------------- *)
instance bring with word
  op rzero = zerow
  op rone  = onew
  op add   = Self.(+^)
  op mul   = andw
  op opp   = oppw

  proof oner_neq0 by apply/onew_neq0
  proof addr0     by apply/xorw0
  proof addrA     by (move=> w1 w2 w3; rewrite xorwA)
  proof addrC     by apply/xorwC
  proof addrK     by apply/xorwK
  proof mulr1     by apply andw1
  proof mulrA     by (move=> w1 w2 w3; rewrite andwA)
  proof mulrC     by apply/andwC
  proof mulrDl    by apply/andwDl
  proof mulrK     by apply/andwK
  proof oppr_id   by trivial.

pred unitw (w:word) = w = onew.
op iandw (w:word) = if w = onew then onew else w.

clone import Ring.ComRing as WRing with 
   type t = word,
   op zeror <- zerow,
   op ( + ) <- (+^),
   op [ - ] <- oppw,
   op oner  <- onew,
   op ( * ) <- andw, 
   op invr  <- iandw,
   pred unit <- unitw
proof *.
realize addrA.     proof. apply xorwA. qed.
realize addrC.     proof. apply xorwC. qed.
realize add0r.     proof. move=> ?;ring. qed.
realize addNr.     proof. move=> ?;ring. qed.
realize oner_neq0. proof. apply onew_neq0. qed.
realize mulrA.     proof. apply andwA. qed.
realize mulrC.     proof. apply andwC. qed.
realize mul1r.     proof. move=> ?;ring. qed. 
realize mulrDl.    proof. apply andwDl. qed. 
realize mulVr.     proof. move=> ?;rewrite /unitw /iandw => -> /=;ring. qed.
realize unitout.   proof. by move=> x;rewrite /unitw /iandw => ->. qed.

realize unitP. 
proof. 
move=> x y; rewrite /unitw !wordP => + i Hi -/(_ i Hi).
by rewrite andwE onewE Hi /#.
qed.

back to top