Another way to solve zkhack-soundness-of-music
 Just noticed that in the verifier program, there are no checks against the commited points. especially the pairing that checks P == H*Z:  let d = E::pairing( (pk + proof.pi_input) + (pk + proof.pi_input) + proof.pi_output.mul(-E::Fr::one()).into(), E::G2Affine::prime_subgroup_generator(), ) == E::pairing(proof.pi_H, setup.rho_Z);  We can make use of this. Let's construct H = 0, in which case P will also be 0. In order to make P = 0, we just need to make sure the private inputs exactly cancel out the public inputs. P = 2 * \rho * (IP_1(\tau) * x + IP_2(\tau) * y + IP_3(\tau) * z) - \rho * (OP_1(\tau) * x + OP_2(\tau) * y + OP_3(\tau) * z) Let the second part equals zero, we get pi_output == pi_output_prime = [0] on G1 then we set pi_input = [- (IP_1(\tau) * x + IP_2(\tau) * y)] on G1, so pk + pi_input equals the point at infinity. (well, actually in order to pass the proof of knowledge check, we can't just set pi_input like that. but, we can just fake public inputs, that's even easier.) That's it! Here is the prover code which generates a fake proof.  pub fn prove_alter( public_inputs: &[E::Fr], private_inputs_len: usize, setup: &Setup, ) -> Proof { let mut fake_pub_inputs = vec![]; let mut fake_pri_inputs = vec![]; for i in 0..public_inputs.len() { fake_pub_inputs.push(public_inputs[i].neg()); } for _ in 0..private_inputs_len { fake_pri_inputs.push(E::Fr::zero()); } let mut private_input_polynomials = E::G1Projective::zero(); let mut private_input_polynomials_prime = E::G1Projective::zero(); for (private_input, private_input_polynomial, private_input_polynomial_prime) in izip!( fake_pub_inputs.iter().chain(fake_pri_inputs.iter()), setup.inputs.iter(), setup.inputs_prime.iter() ) { private_input_polynomials += private_input_polynomial.mul(*private_input); private_input_polynomials_prime += private_input_polynomial_prime.mul(*private_input); } Proof:: { pi_input: private_input_polynomials.into(), pi_input_prime: private_input_polynomials_prime.into(), pi_output: E::G1Affine::zero(), pi_output_prime: E::G1Affine::zero(), pi_K: E::G1Affine::zero(), pi_H: E::G1Affine::zero(), } }