[Feature] Implement snark.verify opcode#3004
Conversation
vicsn
left a comment
There was a problem hiding this comment.
Do you have any recommendation for how explorers should display verifying keys (in e.g. mappings) to users/developers, for them to easily be able to verify their correctness?
Similar to ProvableHQ/leo#28664 which is on the roadmap for Q1, the explorer could verify and display the leo program source code for such stored verifying keys - which I assume we'll want to make effectively immutable.
CC @miazn
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
|
Super exciting stuff y'all! |
This should be up to the developer to parse manually since these are effectively generic byte arrays. We can in theory try to parse byte arrays of size
Immutability of the mapping should be up to the program developer. We also can't really verify the VK because we don't necessarily know the circuit assignment. |
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
synthesizer/program/src/logic/instruction/operation/snark_verify.rs
Outdated
Show resolved
Hide resolved
vicsn
left a comment
There was a problem hiding this comment.
Because we had so many issues with external struct backwards compatibility, I went through every instance of the argument in the code and found two places to extend (nothing too serious):
let mut length = (u16::try_from(result.len()).unwrap()).to_bytes_le().unwrap();, IMO just a single u32 test case would already be sufficient intest_deeply_nested_future.preimage.push(Field::from_u16(argument_locator.index()));, I guess we can just usefrom_u32?
My gut says it's not worth the effort at this to make all of this more strongly typed and tied to each other, because we may make arbitrary changes to the VM, so we will have to continue to rely on a consistent code style + greps.
|
Can you also merge in |
Thank you for doing a pass on this front. Regarding the two findings:
If you agree, I don't think these require changing. |
Signed-off-by: Raymond Chu <14917648+raychu86@users.noreply.github.com>
| let inputs = registers.load(stack, &self.operands[2])?; | ||
| let proof = registers.load(stack, &self.operands[3])?; | ||
|
|
||
| // Verify the signature. |
There was a problem hiding this comment.
| // Verify the signature. | |
| // Verify the proof. |
| /// Returns the operands in the operation. | ||
| #[inline] | ||
| pub fn operands(&self) -> &[Operand<N>] { | ||
| // Sanity check that there are exactly three operands. |
There was a problem hiding this comment.
| // Sanity check that there are exactly three operands. | |
| // Sanity check that there are exactly four operands. |
|
|
||
| // Get the consensus version. | ||
| let consensus_version = N::CONSENSUS_VERSION(current_block_height)?; | ||
| let current_block_height = self.block_store().current_block_height(); |
There was a problem hiding this comment.
current_block_height is available on L79
d0cd
left a comment
There was a problem hiding this comment.
LGTM, found some minor nits.
Motivation
This PR implements the
snark.verifyandsnark.verify.batchopcode, which arefinalize-only operations that verifies a Varuna proof. In order to support this, the array size was also increased from 512 to 2048. These features will activate atConsenusVersion::V14.Examples:
snark.verify r0 r1 r2 into r3r0 is the verifying key (represented by a byte array)
r1 is the verifier inputs (represented by an array of field elements)
r2 is the proof (represented by a byte array)
r3 is the verification results (represented by a boolean)
snark.verify.batch r0 r1 r2 into r3r0 is the array of verifying keys (represented by a 2-D byte array)
r1 is the array of verifier inputs (represented by a 3-D array of field elements)
r2 is the batch proof (represented by a byte array)
r3 is the verification results (represented by a boolean)
Additional Notes
Currently this only supports the native Varuna proofs, but the opcode can be expanded to other proof systems in the future.
The user is required to add the default public input
Field::one()into the verifier inputs.TODO
Test Plan
Tests have been added to check the proofs are properly verified and/or rejected.