1- // SPDX-License-Identifier: UNLICENSED
1+ // SPDX-License-Identifier: MIT
22pragma solidity 0.8.19 ;
33
44import { Halo2Verifier } from "./Halo2Verifier.sol " ;
@@ -9,58 +9,58 @@ type MemoryPointer is uint256;
99/// @notice This contract provides a thin wrapper around the Halo2 verifier
1010/// outputted by `snark-verifier`, exposing a more user-friendly interface.
1111contract OpenVmHalo2Verifier is Halo2Verifier , IOpenVmHalo2Verifier {
12- /// @dev Invalid proof data length
13- error InvalidProofDataLength ();
14-
1512 /// @dev Invalid public values length
16- error InvalidPublicValuesLength ();
13+ error InvalidPublicValuesLength (uint256 expected , uint256 actual );
14+
15+ /// @dev Invalid proof data length
16+ error InvalidProofDataLength (uint256 expected , uint256 actual );
1717
1818 /// @dev Proof verification failed
1919 error ProofVerificationFailed ();
2020
21- /// @dev The length of the proof data, in bytes
21+ /// @dev The length of the proof data, in bytes.
2222 uint256 private constant PROOF_DATA_LENGTH = (12 + 43 ) * 32 ;
2323
24- /// @dev The length of the public values, in bytes. This value is set by OpenVM.
24+ /// @dev The length of the public values, in bytes. This value is set by
25+ /// OpenVM and is guaranteed to be no larger than 8192.
2526 uint256 private constant PUBLIC_VALUES_LENGTH = 32 ;
2627
2728 /// @dev The length of the full proof, in bytes
2829 uint256 private constant FULL_PROOF_LENGTH = (12 + 2 + PUBLIC_VALUES_LENGTH + 43 ) * 32 ;
2930
30- /// @dev The leaf verifier commitment. This value is set by OpenVM.
31- bytes32 public constant LEAF_EXE_COMMIT =
32- bytes32 (0x0071628bff0dcb64201f77ff5c7d869c7073b842e3dadf9e618e8673ef671bfd );
33-
34- /// @dev The version of OpenVM that generated the proof.
35- string public constant OPENVM_VERSION = "v1.0.0 " ;
31+ /// @dev The version of OpenVM that generated this verifier.
32+ string public constant OPENVM_VERSION = "1.0.1-rc.0 " ;
3633
3734 /// @notice A wrapper that constructs the proof into the right format for
3835 /// use with the `snark-verifier` verification.
3936 ///
40- /// @dev This function assumes that `publicValues` encodes one `bytes32`
41- /// hash which is the hash of the public values.
42- ///
43- /// The verifier expected proof format is:
44- /// proof[..12 * 32]: KZG accumulators
37+ /// @dev The verifier expected proof format is:
38+ /// proof[..12 * 32]: KZG accumulator
4539 /// proof[12 * 32..13 * 32]: app exe commit
46- /// proof[13 * 32..14 * 32]: leaf exe commit
40+ /// proof[13 * 32..14 * 32]: app vm commit
4741 /// proof[14 * 32..(14 + PUBLIC_VALUES_LENGTH) * 32]: publicValues[0..PUBLIC_VALUES_LENGTH]
48- /// proof[(14 + PUBLIC_VALUES_LENGTH) * 32..]: Public Values Suffix
42+ /// proof[(14 + PUBLIC_VALUES_LENGTH) * 32..]: Proof Suffix
4943 ///
5044 /// @param publicValues The PVs revealed by the OpenVM guest program.
51- /// @param proofData All components of the proof except the public values,
52- /// leaf and app exe commits. The expected format is:
53- /// `abi.encodePacked(kzgAccumulators , proofSuffix)`
45+ /// @param proofData All components of the proof except the public values and
46+ /// app exe and vm commits. The expected format is:
47+ /// `abi.encodePacked(kzgAccumulator , proofSuffix)`
5448 /// @param appExeCommit The commitment to the OpenVM application executable whose execution
5549 /// is being verified.
56- function verify (bytes calldata publicValues , bytes calldata proofData , bytes32 appExeCommit ) external view {
57- if (publicValues.length != PUBLIC_VALUES_LENGTH) revert InvalidPublicValuesLength ();
58- if (proofData.length != PROOF_DATA_LENGTH) revert InvalidProofDataLength ();
50+ /// @param appVmCommit The commitment to the VM configuration.
51+ function verify (bytes calldata publicValues , bytes calldata proofData , bytes32 appExeCommit , bytes32 appVmCommit )
52+ external
53+ view
54+ {
55+ if (publicValues.length != PUBLIC_VALUES_LENGTH) {
56+ revert InvalidPublicValuesLength (PUBLIC_VALUES_LENGTH, publicValues.length );
57+ }
58+ if (proofData.length != PROOF_DATA_LENGTH) revert InvalidProofDataLength (PROOF_DATA_LENGTH, proofData.length );
5959
6060 // We will format the public values and construct the full proof payload
6161 // below.
6262
63- MemoryPointer proofPtr = _constructProof (publicValues, proofData, appExeCommit);
63+ MemoryPointer proofPtr = _constructProof (publicValues, proofData, appExeCommit, appVmCommit );
6464
6565 uint256 fullProofLength = FULL_PROOF_LENGTH;
6666
@@ -79,56 +79,56 @@ contract OpenVmHalo2Verifier is Halo2Verifier, IOpenVmHalo2Verifier {
7979 //
8080 /// ```solidity
8181 /// bytes memory proof =
82- /// abi.encodePacked(proofData[0:0x180], appExeCommit, leafExeCommit , publicValuesPayload, proofData[0x180:]);
82+ /// abi.encodePacked(proofData[0:0x180], appExeCommit, appVmCommit , publicValuesPayload, proofData[0x180:]);
8383 /// ```
8484 //
8585 /// where `publicValuesPayload` is a memory payload with each byte in
8686 /// `publicValues` separated into its own `bytes32` word.
8787 ///
8888 /// This function does not clean the memory it allocates. Since it is the
89- /// only memory allocation that occurs in the call frame, we know that
90- /// the memory region was not written to before .
89+ /// only memory write that occurs in the call frame, we know that
90+ /// the memory region cannot have been dirtied .
9191 ///
9292 /// @return proofPtr Memory pointer to the beginning of the constructed
93- /// proof.
94- function _constructProof (bytes calldata publicValues , bytes calldata proofData , bytes32 appExeCommit )
95- internal
96- pure
97- returns (MemoryPointer proofPtr )
98- {
93+ /// proof. This pointer does not follow `bytes memory` semantics.
94+ function _constructProof (
95+ bytes calldata publicValues ,
96+ bytes calldata proofData ,
97+ bytes32 appExeCommit ,
98+ bytes32 appVmCommit
99+ ) internal pure returns (MemoryPointer proofPtr ) {
99100 uint256 fullProofLength = FULL_PROOF_LENGTH;
100- bytes32 leafExeCommit = LEAF_EXE_COMMIT;
101101
102102 // The expected proof format using hex offsets:
103103 //
104- // proof[..0x180]: KZG accumulators
104+ // proof[..0x180]: KZG accumulator
105105 // proof[0x180..0x1a0]: app exe commit
106- // proof[0x1a0..0x1c0]: leaf exe commit
106+ // proof[0x1a0..0x1c0]: app vm commit
107107 // proof[0x1c0..(0x1c0 + PUBLIC_VALUES_LENGTH * 32)]: publicValues[0..PUBLIC_VALUES_LENGTH]
108- // proof[(0x1c0 + PUBLIC_VALUES_LENGTH * 32)..]: Public Values Suffix
108+ // proof[(0x1c0 + PUBLIC_VALUES_LENGTH * 32)..]: Proof Suffix
109109
110110 /// @solidity memory-safe-assembly
111111 assembly {
112112 proofPtr := mload (0x40 )
113113 // Allocate the memory as a safety measure.
114114 mstore (0x40 , add (proofPtr, fullProofLength))
115115
116- // Copy the KZG accumulators (length 0x180) into the beginning of
116+ // Copy the KZG accumulator (length 0x180) into the beginning of
117117 // the memory buffer
118118 calldatacopy (proofPtr, proofData.offset, 0x180 )
119119
120- // Copy the App Exe Commit and Leaf Exe Commit into the memory buffer
120+ // Copy the App Exe Commit and App Vm Commit into the memory buffer
121121 mstore (add (proofPtr, 0x180 ), appExeCommit)
122- mstore (add (proofPtr, 0x1a0 ), leafExeCommit )
122+ mstore (add (proofPtr, 0x1a0 ), appVmCommit )
123123
124- // Copy the Public Values Suffix (length 43 * 32 = 0x560) into the
124+ // Copy the Proof Suffix (length 43 * 32 = 0x560) into the
125125 // end of the memory buffer, leaving PUBLIC_VALUES_LENGTH words in
126126 // between for the publicValuesPayload.
127127 //
128- // Begin copying from the end of the KZG accumulators in the
128+ // Begin copying from the end of the KZG accumulator in the
129129 // calldata buffer (0x180)
130- let suffixProofOffset := add (0x1c0 , shl (5 , PUBLIC_VALUES_LENGTH))
131- calldatacopy (add (proofPtr, suffixProofOffset ), add (proofData.offset, 0x180 ), 0x560 )
130+ let proofSuffixOffset := add (0x1c0 , shl (5 , PUBLIC_VALUES_LENGTH))
131+ calldatacopy (add (proofPtr, proofSuffixOffset ), add (proofData.offset, 0x180 ), 0x560 )
132132
133133 // Copy each byte of the public values into the proof. It copies the
134134 // most significant bytes of public values first.
0 commit comments