Require Import floyd.proofauto. (* Import the Verifiable C system *) Require Import progs.verify. (* Import the AST of this C program *) (* The next line is "boilerplate", always required after importing an AST. *) Instance CompSpecs : compspecs. make_compspecs prog. Defined. Definition Vprog : varspecs. mk_varspecs prog. Defined. Definition deSignInteger := Int.xor. (* api spec for verify.c program *) Definition deSignInt_spec := DECLARE _deSignInt WITH bit : int, invKey : int PRE [_bit OF (tint), _invKey OF (tint)] PROP () LOCAL (temp _bit (Vint bit); temp _invKey (Vint invKey)) SEP () POST [tint] PROP() LOCAL (temp ret_temp (Vint (deSignInteger bit invKey))) SEP(). Definition checkSerial_spec := DECLARE _checkSerial WITH q : int, qSigned : int, invKey : int PRE [_q OF (tint), _qSigned OF (tint), _invKey OF (tint)] PROP () LOCAL (temp _q (Vint q); temp _qSigned (Vint qSigned); temp _invKey (Vint invKey)) SEP () POST [tint] PROP () LOCAL (temp ret_temp (Vint (if Int.eq q (deSignInteger qSigned invKey) then Int.repr 1 else Int.repr 0))) SEP (). Local Open Scope logic. Lemma map_cons_cust : forall {A: Type} (f: A -> A -> A) (al: list A) (b: A) (c: A) (dl: list A), (map (fun i => f i b) al ++ f c b :: dl) = ((map (fun i => f i b) (al ++ [c])) ++ dl). Proof. intros. induction al. simpl. reflexivity. simpl. rewrite IHal. reflexivity. Qed. Definition deSignArray_spec := DECLARE _deSignArray WITH bits: val, sh: share, contents : list Z, invKey : Z, size: Z PRE [ _bits OF (tptr tint), _invKey OF tint, _size OF tint ] PROP (readable_share sh; writable_share sh; 0 <= size < Int.max_signed; size = Zlength contents; Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) contents) LOCAL (temp _bits bits; temp _invKey (Vint (Int.repr invKey)); temp _size (Vint (Int.repr size))) SEP (data_at sh (tarray tint size) (map Vint (map Int.repr contents)) bits) POST [tvoid] PROP () LOCAL () SEP (data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr contents))) bits). Fixpoint foralleq (al: list int) (bl: list int) : bool := match al with | a::al' => match bl with | b::bl' => (Int.eq a b) && (foralleq al' bl') | _ => false end | _ => match bl with | b::bl' => false | _ => true end end. Lemma foralleq_refl : forall (al: list int), foralleq al al = true. Proof. intros. induction al as [| a al' IHa']. reflexivity. simpl. rewrite Int.eq_true. rewrite IHa'. reflexivity. Qed. Lemma foralleq_False : forall (al: list int) (bl: list int) (i: Z), (Znth i al Int.zero) <> (Znth i bl Int.zero) -> (foralleq al bl = false). Proof. intro al. induction al as [| a al' IHa']. intros. induction bl. repeat rewrite Znth_nil in H. contradiction H. reflexivity. reflexivity. destruct bl. reflexivity. (* induction bl as [| b bl' IHb']. reflexivity. *) intros. destruct i0. (* case of i = 0 *) rewrite Znth_0_cons in H. rewrite Znth_0_cons in H. simpl. rewrite Int.eq_false. auto. auto. (* case of i > 0 *) rewrite Znth_pos_cons in H. rewrite Znth_pos_cons in H. simpl. assert ((foralleq al' bl) = false). apply IHa' with (bl:=bl) (i:=((Z.pos p) - 1)) in H. auto. rewrite H0. rewrite andb_false_intro2; try auto. apply Pos2Z.is_pos. apply Pos2Z.is_pos. (* case of i < 0 *) rewrite Znth_underflow in H. rewrite Znth_underflow in H. apply repr_inj_unsigned' in H; try omega. rewrite int_max_unsigned_eq. omega. rewrite int_max_unsigned_eq. omega. apply Pos2Z.neg_is_neg. apply Pos2Z.neg_is_neg. Qed. Lemma foralleq_cons : forall (al: list int) (bl: list int) (a: int) (b: int), (Int.eq a b = true) -> (foralleq al bl = foralleq (al ++ [a]) (bl ++ [b])). Proof. intro al. induction al. intros. destruct bl. simpl. rewrite H. reflexivity. simpl. destruct bl. simpl. destruct (Int.eq a i). reflexivity. reflexivity. simpl. destruct (Int.eq a i). reflexivity. reflexivity. intros. destruct bl. simpl. destruct al. simpl. destruct (Int.eq a b). reflexivity. reflexivity. simpl. destruct (Int.eq a b). reflexivity. reflexivity. simpl. rewrite IHal with (a:=a0) (b:=b). reflexivity. auto. Qed. Definition checkArray_spec := DECLARE _checkArray WITH signedBits: val, originalBits: val, sh: share, signedContents : list Z, originalContents : list Z, invKey : Z, size: Z PRE [ _signedBits OF (tptr tint), _originalBits OF (tptr tint), _invKey OF tint, _size OF tint ] PROP (readable_share sh; writable_share sh; 0 <= size < Int.max_signed; size = Zlength signedContents; size = Zlength originalContents; Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) signedContents; Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) originalContents) LOCAL (temp _signedBits signedBits; temp _originalBits originalBits; temp _invKey (Vint (Int.repr invKey)); temp _size (Vint (Int.repr size))) SEP ((data_at sh (tarray tint size) (map Vint (map Int.repr signedContents)) signedBits); (data_at sh (tarray tint size) (map Vint (map Int.repr originalContents)) originalBits)) POST [tint] PROP () LOCAL (temp ret_temp (Vint (if (foralleq (*signedContents originalContents)*) (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) (map Int.repr originalContents) then Int.repr 1 else Int.repr 0))) SEP ((data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) signedBits); (data_at sh (tarray tint size) (map Vint (map Int.repr originalContents)) originalBits)). Definition checkTuple_spec := DECLARE _checkTuple WITH layer_var: (val * list Z), q: Z, topDoll_var: (val * list Z), botDoll_var: (val * list Z), v: Z, k_var: (val * list Z), r: Z, i_var: (val * list Z), j_var: (val * list Z), w: Z, sh: share, key: Z, size: Z (* layer: val, layer_bits: list Z, q: Z, topDoll: val, topDoll_bits: list Z, botDoll: val, botDoll_bits: list Z, v: Z, k: val, k_bits: list Z, r: Z, i: val, i_bits: list Z, j: val, j_bits: list Z, w: Z, sh: share, key: Z, size: Z *) PRE [ _layer OF (tptr tint), _q OF tint, _topDoll OF (tptr tint), _botDoll OF (tptr tint), _v OF tint, _k OF (tptr tint), _r OF tint, _i OF (tptr tint), _j OF (tptr tint), _w OF tint, _key OF tint, _size OF tint ] PROP (readable_share sh; writable_share sh; 0 <= size < Int.max_signed; size = Zlength (snd layer_var); size = Zlength (snd topDoll_var); size = Zlength (snd botDoll_var); size = Zlength (snd k_var); size = Zlength (snd i_var); size = Zlength (snd j_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd layer_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd topDoll_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd botDoll_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd k_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd i_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd j_var)) LOCAL (temp _layer (fst layer_var); temp _q (Vint (Int.repr q)); temp _topDoll (fst topDoll_var); temp _botDoll (fst botDoll_var); temp _v (Vint (Int.repr v)); temp _k (fst k_var); temp _r (Vint (Int.repr r)); temp _i (fst i_var); temp _j (fst j_var); temp _w (Vint (Int.repr w)); temp _key (Vint (Int.repr key)); temp _size (Vint (Int.repr size))) SEP ((data_at sh (tarray tint size) (map Vint (map Int.repr (snd layer_var))) (fst layer_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd k_var))) (fst k_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd i_var))) (fst i_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd j_var))) (fst j_var))) POST [tint] PROP () LOCAL (temp ret_temp (Vint (if ( andb (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))) (andb (Int.eq (Int.repr q) (deSignInteger (Int.repr r) (Int.repr key))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))) ((Int.eq (Int.repr v) (deSignInteger (Int.repr w) (Int.repr key)))))))) then Int.repr 1 else Int.repr 0))) SEP ((data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd k_var)))) (fst k_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd layer_var))) (fst layer_var)); (data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd i_var)))) (fst i_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var)); (data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd j_var)))) (fst j_var)); (data_at sh (tarray tint size) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var))). Definition certifyReceipt_spec := DECLARE _certifyReceipt (* long spec *) WITH layer_var: (val * list Z), topDoll_var: (val * list Z), botDoll_var: (val * list Z), q_v: (Z * Z), k_var: (val * list Z), i_var: (val * list Z), j_var: (val * list Z), r_w: (Z * Z), topFlag_size: (Z * Z), sh: share, topSerialKey: Z, botSerialKey: Z, topTupleKey: Z, botTupleKey: Z PRE [ _topFlag OF tint, _layer OF (tptr tint), _q OF tint, _topDoll OF (tptr tint), _botDoll OF (tptr tint), _v OF tint, _k OF (tptr tint), _r OF tint, _i OF (tptr tint), _j OF (tptr tint), _w OF tint, _size OF tint, _topSerialKey OF tint, _botSerialKey OF tint, _topTupleKey OF tint, _botTupleKey OF tint ] PROP (readable_share sh; writable_share sh; 0 <= (snd topFlag_size) < Int.max_signed; (snd topFlag_size) = Zlength (snd layer_var); (snd topFlag_size) = Zlength (snd topDoll_var); (snd topFlag_size) = Zlength (snd botDoll_var); (snd topFlag_size) = Zlength (snd k_var); (snd topFlag_size) = Zlength (snd i_var); (snd topFlag_size) = Zlength (snd j_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd layer_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd topDoll_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd botDoll_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd k_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd i_var); Forall (fun bit => Int.min_signed <= bit <= Int.max_signed) (snd j_var)) LOCAL (temp _layer (fst layer_var); temp _q (Vint (Int.repr (fst q_v))); temp _topDoll (fst topDoll_var); temp _botDoll (fst botDoll_var); temp _v (Vint (Int.repr (snd q_v))); temp _k (fst k_var); temp _r (Vint (Int.repr (fst r_w))); temp _i (fst i_var); temp _j (fst j_var); temp _w (Vint (Int.repr (snd r_w))); temp _topFlag (Vint (Int.repr (fst topFlag_size))); temp _topSerialKey (Vint (Int.repr topSerialKey)); temp _botSerialKey (Vint (Int.repr botSerialKey)); temp _topTupleKey (Vint (Int.repr topTupleKey)); temp _botTupleKey (Vint (Int.repr botTupleKey)); temp _size (Vint (Int.repr (snd topFlag_size)))) SEP ((data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd layer_var))) (fst layer_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd k_var))) (fst k_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd i_var))) (fst i_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd j_var))) (fst j_var))) POST [tint] PROP () LOCAL (temp ret_temp (Vint (if (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)) then (if (andb (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (snd q_v)) (Int.repr topSerialKey))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))) (andb (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (fst r_w)) (Int.repr topTupleKey))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))) ((Int.eq (Int.repr (snd q_v)) (deSignInteger (Int.repr (snd r_w)) (Int.repr topTupleKey))))))))) then (Int.repr 1) else (Int.repr 0)) else (if (andb (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (snd q_v)) (Int.repr botSerialKey))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))) (andb (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (fst r_w)) (Int.repr botTupleKey))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))) (andb (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))) ((Int.eq (Int.repr (snd q_v)) (deSignInteger (Int.repr (snd r_w)) (Int.repr botTupleKey))))))))) then (Int.repr 1) else (Int.repr 0))))) if (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)) then SEP ((data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd k_var)))) (fst k_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd layer_var))) (fst layer_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd i_var)))) (fst i_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd j_var)))) (fst j_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var))) else SEP ((data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd k_var)))) (fst k_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd layer_var))) (fst layer_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd i_var)))) (fst i_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd j_var)))) (fst j_var)); (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var))). Definition main_spec := DECLARE _main WITH u : unit PRE [] main_pre prog u POST [ tint ] main_post prog u. Definition Gprog : funspecs := augment_funspecs prog [deSignInt_spec; checkSerial_spec; deSignArray_spec; checkArray_spec; checkTuple_spec; certifyReceipt_spec; main_spec]. Lemma body_deSignInt: semax_body Vprog Gprog f_deSignInt deSignInt_spec. Proof. start_function. forward. Qed. Lemma body_checkSerial: semax_body Vprog Gprog f_checkSerial checkSerial_spec. Proof. start_function. fold_types. forward_call (qSigned, invKey). forward_if (PROP ((deSignInteger qSigned invKey) <> q) LOCAL (temp _q2 (Vint (deSignInteger qSigned invKey))) SEP ()). * forward. entailer!. rewrite Int.eq_true with (x := (deSignInteger qSigned invKey)). reflexivity. * forward. entailer!. * forward. entailer!. rewrite Int.eq_false. reflexivity. auto. Qed. Definition deSign_Inv bits sh contents invKey size := EX i: Z, PROP (0 <= i <= size) LOCAL (temp _bits bits; temp _i (Vint (Int.repr i)); temp _invKey (Vint (Int.repr invKey)); temp _size (Vint (Int.repr size))) SEP (data_at sh (tarray tint size) ((map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr (sublist 0 i contents)))) ++ (map Vint (map Int.repr (sublist i size contents)))) bits). Lemma body_deSignArray: semax_body Vprog Gprog f_deSignArray deSignArray_spec. Proof. start_function. forward. forward. forward. forward_while (deSign_Inv bits sh contents invKey size). * (* Prove that current precondition implies loop invariant *) Exists 0. entailer!. rewrite sublist_same. entailer!. auto. auto. * (* Prove that loop invariant implies typechecking condition *) entailer!. * (* Prove postcondition of loop body implies loop invariant *) (* start with bit = bits[i] *) forward. entailer!. rewrite app_Znth2. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. rewrite Znth_map with (d':=Int.zero); try omega. hnf; auto. rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. (* check lower bounds... *) repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. (* next statement *) forward_call((Znth i ((map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr (sublist 0 i contents))) ++ map Int.repr (sublist i size contents)) (Int.zero)), (Int.repr invKey)). (* ans = deSignInt(bit, invKey) *) entailer!. rewrite app_Znth2. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. rewrite Znth_map with (d':=Int.zero); try omega. (* other side... *) rewrite app_Znth2. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist. reflexivity. (* misc generated *) omega. apply H2. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. rewrite initial_world.Zlength_map. rewrite Zlength_sublist. omega. apply H2. omega. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. (* and next steps *) forward. forward. (* end of for loop *) Exists (i+1). entailer!. rewrite upd_Znth_app2. rewrite upd_Znth_ints. rewrite app_Znth2. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. assert ((i - (i - 0)) = 0). omega. rewrite H0. rewrite sublist_nil. simpl. assert ((Znth 0 (map Int.repr (sublist i (Zlength contents) contents)) Int.zero) = (Int.repr (Znth 0 (sublist i (Zlength contents) contents) 0))). apply Znth_map with (d':=0) (al:=(sublist i (Zlength contents) contents)); try omega. rewrite Zlength_sublist; try omega. rewrite H6. rewrite Znth_sublist; try omega. replace (0 + i) with (i) by omega. rewrite <- List.map_cons. rewrite <- list_append_map. rewrite map_cons_cust. assert ([Int.repr (Znth i contents 0)] = (map Int.repr (sublist i (i+1) contents))). rewrite <- Znth_map with (b:=Int.zero); try omega. rewrite <- sublist_len_1; try omega. rewrite sublist_map. reflexivity. rewrite initial_world.Zlength_map; omega. rewrite H7. rewrite <- list_append_map; try omega. rewrite sublist_rejoin; try omega. rewrite list_append_map; try omega. (* deal with second half of array *) rewrite Zlength_sublist; try omega. rewrite sublist_map; try omega. rewrite sublist_sublist; try omega. replace (Zlength contents - i + i) with (Zlength contents) by omega. replace (1 + i) with (i + 1) by omega. apply field_at_data_at_cancel. repeat rewrite initial_world.Zlength_map. rewrite Zlength_sublist; try omega. repeat rewrite initial_world.Zlength_map. repeat rewrite Zlength_sublist; try omega. * (* prove that the loop made the function post condition *) forward. assert (i = Zlength contents). omega. repeat rewrite H5. rewrite sublist_nil. simpl. rewrite sublist_same; try omega. rewrite app_nil_r. apply field_at_data_at_cancel. Qed. Definition check_Inv signedBits originalBits sh signedContents originalContents invKey size := EX i: Z, PROP (0 <= i <= size) LOCAL (temp _signedBits signedBits; temp _originalBits originalBits; temp _i (Vint (Int.repr i)); temp _flag (Vint (if (foralleq (sublist 0 i (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr (sublist 0 i signedContents)))) (sublist 0 i (map Int.repr originalContents))) then Int.one else Int.zero)); temp _invKey (Vint (Int.repr invKey)); temp _size (Vint (Int.repr size))) SEP (data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) signedBits; (data_at sh (tarray tint size) (map Vint (map Int.repr originalContents)) originalBits)). Lemma body_checkArray : semax_body Vprog Gprog f_checkArray checkArray_spec. Proof. start_function. forward_call (signedBits, sh, signedContents, invKey, size). forward. forward. forward. forward. forward_while (check_Inv signedBits originalBits sh signedContents originalContents invKey size). * Exists 0. entailer!. * entailer!. * forward. (* bit1 = signedBits[i] *) entailer!. rewrite Znth_map with (d':=Int.zero); try auto. hnf; auto. repeat rewrite Zlength_map; omega. forward. entailer!. rewrite Znth_map with (d':=Int.zero); try auto. hnf; auto. rewrite Zlength_map; omega. forward_if (PROP () (* this is post condition of if statement *) LOCAL (temp _signedBits signedBits; temp _originalBits originalBits; temp _i (Vint (Int.repr i)); temp _flag (Vint (if (foralleq (sublist 0 (i+1) (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) (sublist 0 (i+1) (map Int.repr originalContents))) then Int.one else Int.zero)); temp _invKey (Vint (Int.repr invKey)); temp _size (Vint (Int.repr size)); temp _bit1 (Znth i (map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef); temp _bit2 (Znth i (map Vint (map Int.repr originalContents)) Vundef)) SEP (data_at sh (tarray tint size) (map Vint (map (fun i => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) signedBits; (data_at sh (tarray tint size) (map Vint (map Int.repr originalContents)) originalBits))). forward. entailer!. rewrite foralleq_False with (i:=i). normalize. assert (sem_cast_neutral (Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef) = Some (Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef)). apply sem_cast_neutral_int with (v:=Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef). exists I32. exists Signed. auto. unfold both_int in H5. rewrite H13 in H5. assert (sem_cast_neutral (Znth i (map Vint (map Int.repr originalContents)) Vundef) = Some (Znth i (map Vint (map Int.repr originalContents)) Vundef)). apply sem_cast_neutral_int with (v:=(Znth i (map Vint (map Int.repr originalContents))) Vundef). exists I32. exists Signed. auto. rewrite H14 in H5. rewrite Znth_map with (d':=Int.zero) in H5; try auto. rewrite Znth_map with (d':=Int.zero) in H5; try auto. rewrite force_val_e in H5. apply typed_true_of_bool in H5. apply negb_true_iff in H5. apply int_eq_false_e in H5. repeat rewrite Znth_sublist. replace (i + 0) with (i) by omega. auto. omega. omega. omega. omega. rewrite Zlength_map; omega. repeat rewrite Zlength_map; omega. forward. entailer!. assert (sem_cast_neutral (Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef) = Some (Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef)). apply sem_cast_neutral_int with (v:=Znth i (map Vint (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents))) Vundef). exists I32. exists Signed. auto. unfold both_int in H5. rewrite H13 in H5. assert (sem_cast_neutral (Znth i (map Vint (map Int.repr originalContents)) Vundef) = Some (Znth i (map Vint (map Int.repr originalContents)) Vundef)). apply sem_cast_neutral_int with (v:=(Znth i (map Vint (map Int.repr originalContents))) Vundef). exists I32. exists Signed. auto. rewrite H14 in H5. rewrite Znth_map with (d':=Int.zero) in H5; try auto. rewrite Znth_map with (d':=Int.zero) in H5; try auto. rewrite force_val_e in H5. apply typed_false_of_bool in H5. apply negb_false_iff in H5. rewrite Vint_inj'. rewrite map_sublist. rewrite map_sublist. rewrite sublist_sublist; try omega. replace (0+0) with (0) by omega. replace (i+0) with (i) by omega. rewrite foralleq_cons with (a:= Znth i (map (fun i : int => deSignInteger i (Int.repr invKey)) (map Int.repr signedContents)) Int.zero) (b:= (Znth i (map Int.repr originalContents) Int.zero)) (al:= (sublist 0 i (map (fun i0 : int => deSignInteger i0 (Int.repr invKey)) (map Int.repr signedContents)))) (bl:= (sublist 0 i (map Int.repr originalContents))). rewrite <- sublist_one with (hi:=i+1); try omega. rewrite sublist_rejoin with (mid:=i); try omega. rewrite <- sublist_one with (hi:=i+1); try omega. rewrite sublist_rejoin with (mid:=i); try omega. reflexivity. (* bounds checking... *) repeat rewrite Zlength_map; try omega. repeat rewrite Zlength_map; try omega. repeat rewrite Zlength_map; try omega. repeat rewrite Zlength_map; try omega. apply H5. repeat rewrite Zlength_map; try omega. repeat rewrite Zlength_map; try omega. (* after the loop *) forward. Exists (i+1). rewrite map_sublist. rewrite map_sublist. rewrite sublist_sublist; try omega. replace (0+0) with (0) by omega. replace (i+1+0) with (i+1) by omega. entailer!. (* end of for; return 1 *) * rewrite map_sublist. rewrite map_sublist. rewrite sublist_sublist; try omega. replace (0+0) with (0) by omega. replace (i+0) with (i) by omega. forward. rewrite sublist_same; try omega. rewrite sublist_same; try omega. entailer!. rewrite Zlength_map. rewrite <- H1. omega. repeat rewrite Zlength_map. omega. Qed. Lemma body_checkTuple: semax_body Vprog Gprog f_checkTuple checkTuple_spec. Proof. start_function. forward. forward. forward_call ((fst k_var), (fst layer_var), sh, (snd k_var), (snd layer_var), key, size). (* prove the preconditions which are our preconditions... *) split3; try auto. forward. forward_call ((Int.repr q), (Int.repr r), (Int.repr key)). forward. forward_call ((fst i_var), (fst topDoll_var), sh, (snd i_var), (snd topDoll_var), key, size). split3; try auto. forward. forward_call ((fst j_var), (fst botDoll_var), sh, (snd j_var), (snd botDoll_var), key, size). split3; try auto. forward. forward_call ((Int.repr v), (Int.repr w), (Int.repr key)). forward. forward. (* end of commands, lets do a check on these post conditions *) entailer!. (* clears out all those arrays... *) (* split each set of results then things automatically come out *) destruct (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))); destruct (Int.eq (Int.repr q) (deSignInteger (Int.repr r) (Int.repr key))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr key)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))); destruct (Int.eq (Int.repr v) (deSignInteger (Int.repr w) (Int.repr key))); try auto. Qed. Lemma body_certifyReceipt: semax_body Vprog Gprog f_certifyReceipt certifyReceipt_spec. Proof. start_function. forward. forward. forward. forward. forward_if (PROP ( ) (* where are we after the if concludes? *) LOCAL (temp _val (Vint (Int.repr 0)); temp _flag (Vint (Int.repr 1)); temp _layer (fst layer_var); temp _q (Vint (Int.repr (fst q_v))); temp _topDoll (fst topDoll_var); temp _botDoll (fst botDoll_var); temp _v (Vint (Int.repr (snd q_v))); temp _k (fst k_var); temp _r (Vint (Int.repr (fst r_w))); temp _i (fst i_var); temp _j (fst j_var); temp _w (Vint (Int.repr (snd r_w))); temp _topFlag (Vint (Int.repr (fst topFlag_size))); temp _topSerialKey (Vint (Int.repr topSerialKey)); temp _botSerialKey (Vint (Int.repr botSerialKey)); temp _topTupleKey (Vint (Int.repr topTupleKey)); temp _botTupleKey (Vint (Int.repr botTupleKey)); temp _size (Vint (Int.repr (snd topFlag_size))); temp _serKey (Vint (if (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)) then (Int.repr topSerialKey) else (Int.repr botSerialKey))); temp _tupKey (Vint (if (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)) then (Int.repr topTupleKey) else (Int.repr botTupleKey)))) SEP (data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd layer_var))) (fst layer_var); data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd topDoll_var))) (fst topDoll_var); data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd botDoll_var))) (fst botDoll_var); data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd k_var))) (fst k_var); data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd i_var))) (fst i_var); data_at sh (tarray tint (snd topFlag_size)) (map Vint (map Int.repr (snd j_var))) (fst j_var))). * (* topFlag == 1 *) forward. forward. entailer!. rewrite H12; repeat rewrite Int.eq_true; try auto. * (* topFlag != 1 *) forward. forward. entailer!. repeat rewrite Int.eq_false; try auto. * forward_call ((Int.repr (fst q_v)), (Int.repr (snd q_v)), (if Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1) then Int.repr topSerialKey else Int.repr botSerialKey)). forward. forward_call (layer_var, (fst q_v), topDoll_var, botDoll_var, (snd q_v), k_var, (fst r_w), i_var, j_var, (snd r_w), sh, (if Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1) then topTupleKey else botTupleKey), (snd topFlag_size)). (* preconditions *) entailer!. destruct (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)); auto. repeat split3; try auto. forward. forward. entailer!. (* check return value *) (* flag is 1 *) destruct (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)). destruct (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (snd q_v)) (Int.repr topSerialKey))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))); destruct (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (fst r_w)) (Int.repr topTupleKey))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr topTupleKey)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))); destruct (Int.eq (Int.repr (snd q_v)) (deSignInteger (Int.repr (snd r_w)) (Int.repr topTupleKey))); try auto. (* not 1 *) destruct (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (snd q_v)) (Int.repr botSerialKey))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd k_var))) (map Int.repr (snd layer_var))); destruct (Int.eq (Int.repr (fst q_v)) (deSignInteger (Int.repr (fst r_w)) (Int.repr botTupleKey))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd i_var))) (map Int.repr (snd topDoll_var))); destruct (foralleq (map (fun i => deSignInteger i (Int.repr botTupleKey)) (map Int.repr (snd j_var))) (map Int.repr (snd botDoll_var))); destruct (Int.eq (Int.repr (snd q_v)) (deSignInteger (Int.repr (snd r_w)) (Int.repr botTupleKey))); try auto. (* check return seps *) destruct (Int.eq (Int.repr (fst topFlag_size)) (Int.repr 1)); entailer!. (* woo! *) Qed. (* Contents of the global arrays *) Definition qVals_contents := [15; 5463; 12; 75; 231; 1431; 735; 134]. Definition processedQVals_contents := [15; 5463; 12; 75; 231; 1431; 735; 134]. Lemma body_main : semax_body Vprog Gprog f_main main_spec. Proof. name qVals _qVals. name processedQVals _processedQVals. start_function. forward. forward. forward_call ((Int.repr 15687), (Int.repr 4231)). forward_call ((Int.repr 15687), (deSignInteger (Int.repr 15687) (Int.repr 4231)), (Int.repr 4231)). forward_call (processedQVals, Ews, processedQVals_contents, 4231, 8). split. auto. split. auto. split3; try auto. rewrite int_max_signed_eq; omega. repeat constructor; computable. forward_call (processedQVals, qVals, Ews, (map Int.signed (map (fun i : int => deSignInteger i (Int.repr 4231)) (map Int.repr processedQVals_contents))), qVals_contents, 4231, 8). repeat split; try auto. omega. repeat constructor; try apply Int.signed_range. repeat constructor; computable. forward. Qed. Existing Instance NullExtension.Espec. Lemma all_funcs_correct: semax_func Vprog Gprog (prog_funct prog) Gprog. Proof. unfold Gprog, prog, prog_funct; simpl. semax_func_cons body_deSignInt. semax_func_cons body_checkSerial. semax_func_cons body_deSignArray. semax_func_cons body_checkArray. semax_func_cons body_checkTuple. semax_func_cons body_certifyReceipt. semax_func_cons body_main. Qed.