induction n0; intuition; simpl in *.
destruct ls; simpl.
trivial.
eauto.
Qed.
Definition vector_secondPart_h(A : Set)(m1 m2 : nat)(v : Vector.t A (m1 + m2)) : {ls : list A | length ls = m2}.
refine (exist _ (skipn m1 (Vector.to_list v)) _).
rewrite skipn_length.
rewrite to_list_length.
omega.
Defined.
Fixpoint secondPart(A : Set)(m1 m2 : nat)(v : Vector.t A (m1 + m2)) : Vector.t A m2 :=
of_sig_list (vector_secondPart_h m1 m2 v).
Section OWP_impl_HCP.
Variable n : nat.
(* f is a one-way permutation *)
Variable f : Bvector n -> Bvector n.
Variable f_inv : Bvector n -> Bvector n.
Hypothesis f_inv1 : forall v, f (f_inv v) = v.
Hypothesis f_inv2 : forall v, f_inv (f v) = v.
Variable A : Bvector (n + n) -> bool -> Comp bool.
Definition dotProduct(n : nat)(v1 v2 : Bvector n) :=
Vector.fold_left2 (fun acc b1 b2 => (xorb acc (andb b1 b2))) false v1 v2.
(* f' is a one-way function for vectors of length n + n *)
Definition f'(v : Bvector (n + n)) :=
Vector.append (f (firstPart n n v)) (secondPart n n v).
Definition b(v : Bvector (n + n)) := (dotProduct (firstPart n n v) (secondPart n n v)).
Definition OWP_HCP_B(v : Bvector n) : Comp (Bvector n) :=
ret v.

(* Specifications: *)
Theorem OWP_HCP :
HCP_Advantage f' b A <= (OWP_Advantage f OWP_HCP_B).