Section ProofOfKnowledge.
Context `{p : SigmaProtocol}.
Variable r_commit_length : nat.
Variable P_commit_f : Bvector r_commit_length -> Blist -> Blist -> (P_State * Commitment).
Variable r_respond_length : nat.
Variable P_respond_f : Bvector r_respond_length -> P_State -> Bvector t -> Response.
(* Hypothesis P_correct : forall x y e resp, evalDist (v <- {0, 1}^r_length; ret (P x y v e)) resp == evalDist (P_respond e) resp. *)
(* completeness (non-triviality) is the same as in SigmaProtocol *)
Variable v_firstn : forall n1 n2, Bvector (n1 + n2)%nat -> Bvector n1.
Variable v_skipn : forall n1 n2, Bvector (n1 + n2)%nat -> Bvector n2.
Hypothesis v_firstn_correct : forall n1 n2 v1 v2,  (v_firstn n1 n2 (VectorDef.append v1 v2)) = v1.
Hypothesis v_skipn_correct : forall n1 n2 v1 v2,  (v_skipn n1 n2 (VectorDef.append v1 v2)) = v2.
Hypothesis firstn_skipn_correct : forall n1 n2 (v : Bvector (n1 + n2)), v = (VectorDef.append (v_firstn n1 n2 v) (v_skipn n1 n2 v)).
Definition Protocol_f x w r :=
r1 <-! v_firstn r_commit_length r_respond_length r;
r2 <-! v_skipn r_commit_length r_respond_length r;
[s_P, a] <-* P_commit_f r1 x w;
e <- V_challenge x a;
z <-! P_respond_f r2 s_P e;
ret (a, e, z).
Definition little_p x w r := Pr[[a, e, z] <--** Protocol_f x w r; V_accept x a e z].
Local Open Scope list_scope.
Definition knowledgeExtractor (x : Blist)(P : Bvector t -> Response) := ret (false :: nil).
Definition knowledge_soundness(k : nat -> Rat) :=
forall x y r,
let r1 := v_firstn r_commit_length r_respond_length r in
let r2 := v_skipn r_commit_length r_respond_length r in
let (s_P, a) := P_commit_f r1 x y in
(ratSubtract (little_p x y r) (k (length x))) <= Pr[y' <- knowledgeExtractor x (P_respond_f r2 s_P); ret (R x y')].

Theorem sigma_knowledge_soundness : knowledge_soundness (fun x => 1 / expnat 2 x).