diff --git a/src/codegen.rs b/src/codegen.rs index 547a90a..30d93a6 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -167,6 +167,7 @@ impl<'a> SolidityGenerator<'a> { let constants = { let domain = self.vk.get_domain(); let vk_digest = fr_to_u256(vk_transcript_repr(self.vk)); + let num_instances = U256::from(self.num_instances); let k = U256::from(domain.k()); let n_inv = fr_to_u256(bn256::Fr::from(1 << domain.k()).invert().unwrap()); let omega = fr_to_u256(domain.get_omega()); @@ -175,7 +176,6 @@ impl<'a> SolidityGenerator<'a> { let l = self.meta.rotation_last.unsigned_abs() as u64; fr_to_u256(domain.get_omega_inv().pow_vartime([l])) }; - let num_instances = U256::from(self.num_instances); let has_accumulator = U256::from(self.acc_encoding.is_some()); let acc_offset = self .acc_encoding @@ -195,12 +195,12 @@ impl<'a> SolidityGenerator<'a> { let neg_s_g2 = g2_to_u256s(-self.params.s_g2()); vec![ ("vk_digest", vk_digest), + ("num_instances", num_instances), ("k", k), ("n_inv", n_inv), ("omega", omega), ("omega_inv", omega_inv), ("omega_inv_to_l", omega_inv_to_l), - ("num_instances", num_instances), ("has_accumulator", has_accumulator), ("acc_offset", acc_offset), ("num_acc_limbs", num_acc_limbs), @@ -267,7 +267,7 @@ impl<'a> SolidityGenerator<'a> { Halo2Verifier { scheme: self.scheme, - vk: (!separate).then_some(vk), + embedded_vk: (!separate).then_some(vk), vk_len, vk_mptr, num_neg_lagranges: self.meta.rotation_last.unsigned_abs() as usize, @@ -301,15 +301,18 @@ impl<'a> SolidityGenerator<'a> { Gwc19 => unimplemented!(), }; - itertools::max(chain![ - // Hashing advice commitments - chain![self.meta.num_advices().into_iter()].map(|n| n * 2 + 1), - // Hashing evaluations - [self.meta.num_evals + 1], + itertools::max([ + // Keccak256 input (can overwrite vk) + itertools::max(chain![ + self.meta.num_advices().into_iter().map(|n| n * 2 + 1), + [self.meta.num_evals + 1], + ]) + .unwrap() + .saturating_sub(vk.len() / 0x20), // PCS computation - [pcs_computation], + pcs_computation, // Pairing - [12], + 12, ]) .unwrap() * 0x20 diff --git a/src/codegen/template.rs b/src/codegen/template.rs index e25f723..55753f9 100644 --- a/src/codegen/template.rs +++ b/src/codegen/template.rs @@ -25,7 +25,7 @@ impl Halo2VerifyingKey { #[template(path = "Halo2Verifier.sol")] pub(crate) struct Halo2Verifier { pub(crate) scheme: BatchOpenScheme, - pub(crate) vk: Option, + pub(crate) embedded_vk: Option, pub(crate) vk_len: usize, pub(crate) proof_len: usize, pub(crate) vk_mptr: Ptr, diff --git a/templates/Halo2Verifier.sol b/templates/Halo2Verifier.sol index 81b2db6..505d58a 100644 --- a/templates/Halo2Verifier.sol +++ b/templates/Halo2Verifier.sol @@ -13,12 +13,12 @@ contract Halo2Verifier { uint256 internal constant VK_MPTR = {{ vk_mptr }}; uint256 internal constant VK_DIGEST_MPTR = {{ vk_mptr }}; - uint256 internal constant K_MPTR = {{ vk_mptr + 1 }}; - uint256 internal constant N_INV_MPTR = {{ vk_mptr + 2 }}; - uint256 internal constant OMEGA_MPTR = {{ vk_mptr + 3 }}; - uint256 internal constant OMEGA_INV_MPTR = {{ vk_mptr + 4 }}; - uint256 internal constant OMEGA_INV_TO_L_MPTR = {{ vk_mptr + 5 }}; - uint256 internal constant NUM_INSTANCES_MPTR = {{ vk_mptr + 6 }}; + uint256 internal constant NUM_INSTANCES_MPTR = {{ vk_mptr + 1 }}; + uint256 internal constant K_MPTR = {{ vk_mptr + 2 }}; + uint256 internal constant N_INV_MPTR = {{ vk_mptr + 3 }}; + uint256 internal constant OMEGA_MPTR = {{ vk_mptr + 4 }}; + uint256 internal constant OMEGA_INV_MPTR = {{ vk_mptr + 5 }}; + uint256 internal constant OMEGA_INV_TO_L_MPTR = {{ vk_mptr + 6 }}; uint256 internal constant HAS_ACCUMULATOR_MPTR = {{ vk_mptr + 7 }}; uint256 internal constant ACC_OFFSET_MPTR = {{ vk_mptr + 8 }}; uint256 internal constant NUM_ACC_LIMBS_MPTR = {{ vk_mptr + 9 }}; @@ -70,10 +70,10 @@ contract Halo2Verifier { uint256 internal constant PAIRING_RHS_Y_MPTR = {{ theta_mptr + 25 }}; function verifyProof( - {%- match vk %} - {%- when Some with (vk) %} + {%- match self.embedded_vk %} {%- when None %} address vk, + {%- else %} {%- endmatch %} bytes calldata proof, uint256[] calldata instances @@ -223,25 +223,15 @@ contract Halo2Verifier { let success := true { - {%- match vk %} - {%- when Some with (vk) %} - // Load vk into memory - {%- for (name, chunk) in vk.constants %} + {%- match self.embedded_vk %} + {%- when Some with (embedded_vk) %} + // Load vk_digest and num_instances of vk into memory + {%- for (name, chunk) in embedded_vk.constants[..2] %} mstore({{ vk_mptr + loop.index0 }}, {{ chunk|hex_padded(64) }}) // {{ name }} {%- endfor %} - {%- for (x, y) in vk.fixed_comms %} - {%- let offset = vk.constants.len() %} - mstore({{ vk_mptr + offset + 2 * loop.index0 }}, {{ x|hex_padded(64) }}) // fixed_comms[{{ loop.index0 }}].x - mstore({{ vk_mptr + offset + 2 * loop.index0 + 1 }}, {{ y|hex_padded(64) }}) // fixed_comms[{{ loop.index0 }}].y - {%- endfor %} - {%- for (x, y) in vk.permutation_comms %} - {%- let offset = vk.constants.len() + 2 * vk.fixed_comms.len() %} - mstore({{ vk_mptr + offset + 2 * loop.index0 }}, {{ x|hex_padded(64) }}) // permutation_comms[{{ loop.index0 }}].x - mstore({{ vk_mptr + offset + 2 * loop.index0 + 1 }}, {{ y|hex_padded(64) }}) // permutation_comms[{{ loop.index0 }}].y - {%- endfor %} {%- when None %} - // Copy vk into memory - extcodecopy(vk, VK_MPTR, 0x00, {{ vk_len|hex() }}) + // Copy vk_digest and num_instances of vk into memory + extcodecopy(vk, VK_MPTR, 0x00, 0x40) {%- endmatch %} // Check valid length of proof @@ -317,6 +307,27 @@ contract Halo2Verifier { // TODO {%- endmatch %} + {%~ match self.embedded_vk %} + {%- when Some with (embedded_vk) %} + // Load full vk into memory + {%- for (name, chunk) in embedded_vk.constants %} + mstore({{ vk_mptr + loop.index0 }}, {{ chunk|hex_padded(64) }}) // {{ name }} + {%- endfor %} + {%- for (x, y) in embedded_vk.fixed_comms %} + {%- let offset = embedded_vk.constants.len() %} + mstore({{ vk_mptr + offset + 2 * loop.index0 }}, {{ x|hex_padded(64) }}) // fixed_comms[{{ loop.index0 }}].x + mstore({{ vk_mptr + offset + 2 * loop.index0 + 1 }}, {{ y|hex_padded(64) }}) // fixed_comms[{{ loop.index0 }}].y + {%- endfor %} + {%- for (x, y) in embedded_vk.permutation_comms %} + {%- let offset = embedded_vk.constants.len() + 2 * embedded_vk.fixed_comms.len() %} + mstore({{ vk_mptr + offset + 2 * loop.index0 }}, {{ x|hex_padded(64) }}) // permutation_comms[{{ loop.index0 }}].x + mstore({{ vk_mptr + offset + 2 * loop.index0 + 1 }}, {{ y|hex_padded(64) }}) // permutation_comms[{{ loop.index0 }}].y + {%- endfor %} + {%- when None %} + // Copy full vk into memory + extcodecopy(vk, VK_MPTR, 0x00, {{ vk_len|hex() }}) + {%- endmatch %} + // Read accumulator from instances if mload(HAS_ACCUMULATOR_MPTR) { let num_limbs := mload(NUM_ACC_LIMBS_MPTR)