# How to adapt verifier contract to new Setup ### What should be changed in the contract for a new setup. ```solidity= // different block size will have different setup thus different vk and gammaABC function verifyingKey(uint16 block_size) internal pure returns (uint256[22] memory vk) { vk[0] = {{.G1.Alpha.X.String}}; vk[1] = {{.G1.Alpha.Y.String}}; vk[2] = {{.G2.Beta.X.A1.String}}; vk[3] = {{.G2.Beta.X.A0.String}}; vk[4] = {{.G2.Beta.Y.A1.String}}; vk[5] = {{.G2.Beta.Y.A0.String}}; vk[6] = {{.G2.Gamma.X.A1.String}}; vk[7] = {{.G2.Gamma.X.A0.String}}; vk[8] = {{.G2.Gamma.Y.A1.String}}; vk[9] = {{.G2.Gamma.Y.A0.String}}; vk[10] = {{.G2.Delta.X.A1.String}}; vk[11] = {{.G2.Delta.X.A0.String}}; vk[12] = {{.G2.Delta.Y.A1.String}}; vk[13] = {{.G2.Delta.Y.A0.String}}; vk[14] = {{.CommitmentKey.G.X.A1.String}}; vk[15] = {{.CommitmentKey.G.X.A0.String}}; vk[16] = {{.CommitmentKey.G.Y.A1.String}}; vk[17] = {{.CommitmentKey.G.Y.A0.String}}; vk[18] = {{.CommitmentKey.GRootSigmaNeg.X.A1.String}}; vk[19] = {{.CommitmentKey.GRootSigmaNeg.X.A0.String}}; vk[20] = {{.CommitmentKey.GRootSigmaNeg.Y.A1.String}}; vk[21] = {{.CommitmentKey.GRootSigmaNeg.Y.A0.String}}; return vk; } function ic(uint16 block_size) internal pure returns (uint256[] memory gammaABC) { gammaABC = new uint256[](10); {{- range $i, $ki := .G1.K }} {{- $j := double $i }} gammaABC[{{$j}}] = {{$ki.X.String}}; // vk.K[{{$i}}].X gammaABC[{{sub $j -1}}] = {{$ki.Y.String}}; // vk.K[{{$i}}].Y {{- end }} return gammaABC; } ``` ### What should be changed for a new circuit ```solidity= // here it will inputs commitments[proofNumber * 4], commitments[proofNumber * 4 + 1] and many(1 to public inputs count) proof_inputs[determined by the committed public inputs] // here we use one because we only have one public_inputs committed for the circuit. function toBytes(uint256 x, uint256 y, uint256 z) public pure returns (bytes memory) { bytes memory b = new bytes(96); assembly { mstore(add(b, 32), x) } assembly { mstore(add(b, 64), y) } // depends on how much public inputs are committed assembly { mstore(add(b, 96), z) } return b; } function accumulate( uint256[] memory in_proof, uint256[] memory proof_inputs, // public inputs, length is num_inputs * num_proofs uint256[] memory commitments, uint256 num_proofs ) internal view returns ( uint256[] memory proofsAandC, uint256[] memory inputAccumulators, uint256[] memory proofCommitmentKx, uint256[] memory proofCommitmentPokKx ) { uint256 q = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 numPublicInputs = proof_inputs.length / num_proofs; for (uint256 proofNumber = 0; proofNumber < num_proofs; proofNumber++) { bytes memory commitmentBzs = toBytes(commitments[proofNumber*4], commitments[proofNumber*4+1], proof_inputs[proofNumber*numPublicInputs]); proof_inputs[proofNumber*numPublicInputs+numPublicInputs-1] = calcHash(commitmentBzs); } ... } function verifyProof( uint256[] memory in_proof, uint256[] memory proof_inputs, uint256[] memory commitments, // G1 Points commitment/commitmentPok uint16 block_size) public view returns (bool) { // cal the proof inputs bytes memory commitmentBzs = toBytes(commitments[0], commitments[1], proof_inputs[0]); ... } ``` ### The circuit used in the example above. ```go= type Circuit struct { PreImage frontend.Variable Hash frontend.Variable `gnark:",public"` Any0 frontend.Variable `gnark:",public"` Any1 frontend.Variable `gnark:",public"` GKRs gkr.GkrCircuit } func (circuit *Circuit) Define(api frontend.API) error { // hash function for i := 0; i < 1; i++ { circuit.Hash2BySamePreImageHint(api) } api.AssertIsDifferent(circuit.Any0, circuit.Any1) // here we use PreImage private as committed // here we use Hash public as committed // Hash is the first public value, thus we will use the proof_inputs[0] into the toBytes function. return circuit.GKRs.AssertValid(api, circuit.PreImage, circuit.Hash) } ```