-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat(protocol): proof verification aggregation #17938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,7 +148,8 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents { | |
/// @inheritdoc ITaikoL1 | ||
function proveBlocks( | ||
uint64[] calldata _blockIds, | ||
bytes[] calldata _inputArr | ||
bytes[] calldata _inputArr, | ||
bytes proof | ||
) | ||
external | ||
whenNotPaused | ||
|
@@ -162,9 +163,14 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents { | |
|
||
TaikoData.Config memory config = getConfig(); | ||
|
||
IVerifier.Context[] memory ctxs = new IVerifier.Context[](_blockIds.length); | ||
Brechtpd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
TaikoData.Transition[] memory trans = new TaikoData.Transition[](_blockIds.length); | ||
|
||
for (uint256 i; i < _blockIds.length; ++i) { | ||
_proveBlock(_blockIds[i], _inputArr[i], config); | ||
(ctxs[i], trans[i]) = _proveBlock(_blockIds[i], _inputArr[i], config); | ||
} | ||
|
||
IVerifier(verifier).verifyProof(ctxs, trans, proof); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a compilation error, due to this outter And also this yields into another problem, with an example: And thus, the verifier contract address itself differs from block to block. so aggregating multiple, continuous blocks and verify with one go, will only work (in the current design at least!) if we have the exact same logic (contract) to verify (so same tiers), otherwise no. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can only aggregate proofs for the same tier together, but the proofs may correspond to blocks that are not consecutive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but then with ever 500-100th zk tier blocks in practice it will be useful for tee only. (At least for now.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I have now added the required checks to make sure only the same proofs can be aggregrated. |
||
} | ||
|
||
/// @inheritdoc ITaikoL1 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,7 @@ contract SgxVerifier is EssentialContract, IVerifier { | |
/// @param instance The address of the SGX instance. | ||
event InstanceDeleted(uint256 indexed id, address indexed instance); | ||
|
||
error SGX_INVALID_INPUT(); | ||
error SGX_ALREADY_ATTESTED(); | ||
error SGX_INVALID_ATTESTATION(); | ||
error SGX_INVALID_INSTANCE(); | ||
|
@@ -144,8 +145,8 @@ contract SgxVerifier is EssentialContract, IVerifier { | |
|
||
/// @inheritdoc IVerifier | ||
function verifyProof( | ||
Context calldata _ctx, | ||
TaikoData.Transition calldata _tran, | ||
Context[] calldata _ctx, | ||
TaikoData.Transition[] calldata _tran, | ||
TaikoData.TierProof calldata _proof | ||
) | ||
external | ||
|
@@ -154,19 +155,35 @@ contract SgxVerifier is EssentialContract, IVerifier { | |
// Do not run proof verification to contest an existing proof | ||
if (_ctx.isContesting) return; | ||
|
||
if (_ctx.length != _tran.length) { | ||
revert SGX_INVALID_INPUT(); | ||
} | ||
|
||
// Size is: 89 bytes | ||
// 4 bytes + 20 bytes + 65 bytes (signature) = 89 | ||
if (_proof.data.length != 89) revert SGX_INVALID_PROOF(); | ||
// 4 bytes + 20 bytes + 20 bytes + 65 bytes (signature) = 109 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the current SGX prover doesn't support multiple blocks, can we ensure the length of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The inputs into the verification are still changed so a bit tricky. If length is 1 we could use the old verification path, but then this would be a special case and proof aggregation on a single proof would not be valid. Seems easier if aggregation is always used even if there's only a single proof, otherwise we need multiple verification paths. |
||
if (_proof.data.length != 109) revert SGX_INVALID_PROOF(); | ||
|
||
uint32 id = uint32(bytes4(_proof.data[:4])); | ||
address newInstance = address(bytes20(_proof.data[4:24])); | ||
|
||
address oldInstance = ECDSA.recover( | ||
LibPublicInput.hashPublicInputs( | ||
address oldInstance = address(bytes20(_proof.data[4:24])); | ||
address newInstance = address(bytes20(_proof.data[24:44])); | ||
bytes memory signature = _proof.data[44:]; | ||
|
||
// Collect public inputs | ||
bytes32[] memory public_inputs = new bytes32[](_tran.length + 1); | ||
// First public input is the block proving program key | ||
public_inputs[0] = bytes32(oldInstance); | ||
// All other inputs are the block program public inputs (a single 32 byte value) | ||
for (uint i = 0; i < _tran.length; i++) { | ||
// TODO: For now this assumes the new instance public key to remain the same | ||
public_inputs[i + 1] = LibPublicInput.hashPublicInputs( | ||
_tran, address(this), newInstance, _ctx.prover, _ctx.metaHash, taikoChainId() | ||
), | ||
_proof.data[24:] | ||
); | ||
); | ||
} | ||
|
||
require(oldInstance, ECDSA.recover( | ||
keccak256(abi.encodePacked(public_inputs)), | ||
signature | ||
), "invalid signature"); | ||
|
||
if (!_isInstanceValid(id, oldInstance)) revert SGX_INVALID_INSTANCE(); | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.