Skip to content
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

feat(protocol): add aggregated sgx verify test #18160

Merged
merged 24 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a884979
add aggregated sgx verify test
smtmfft Sep 22, 2024
19e0609
update risc0 batch verify contract
smtmfft Sep 24, 2024
cd9913a
forge fmt & update contract layout tables
smtmfft Sep 24, 2024
a5f8965
Merge branch 'main' into sgx-agg-verify
dantaik Sep 24, 2024
5b3d637
Update packages/protocol/contracts/layer1/verifiers/Risc0Verifier.sol
smtmfft Sep 24, 2024
03fdda8
add aggregated sgx verify test
smtmfft Sep 22, 2024
2147cb6
update risc0 batch verify contract
smtmfft Sep 24, 2024
f4ede75
forge fmt & update contract layout tables
smtmfft Sep 24, 2024
3b7c48b
Update packages/protocol/contracts/layer1/verifiers/Risc0Verifier.sol
smtmfft Sep 24, 2024
29ad552
Merge branch 'sgx-agg-verify' of https://github.com/taikoxyz/taiko-mo…
smtmfft Sep 24, 2024
a6d44c4
Update packages/protocol/contracts/layer1/verifiers/SgxVerifier.sol
smtmfft Sep 24, 2024
be3de06
Merge branch 'sgx-agg-verify' of https://github.com/taikoxyz/taiko-mo…
smtmfft Sep 24, 2024
906520d
fix review comments
smtmfft Sep 24, 2024
2bf2b16
fix compile
smtmfft Sep 24, 2024
78079f8
fix compile
smtmfft Sep 24, 2024
1f8ec37
Update SgxVerifier.sol
dantaik Sep 24, 2024
9139115
Update SgxVerifier.sol
dantaik Sep 24, 2024
f6202a5
Update SgxVerifier.t.sol
dantaik Sep 24, 2024
9899218
Revert "Update SgxVerifier.t.sol"
dantaik Sep 24, 2024
03d2376
Update SgxVerifier.t.sol
dantaik Sep 24, 2024
e9f4099
forge fmt & update contract layout tables
dantaik Sep 24, 2024
3aa7f17
Merge branch 'main' into sgx-agg-verify
YoGhurt111 Sep 26, 2024
1127b08
forge fmt & update contract layout tables
YoGhurt111 Sep 26, 2024
fc0aa5a
Merge branch 'main' into sgx-agg-verify
davidtaikocha Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions packages/protocol/contracts/layer1/verifiers/Risc0Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ contract Risc0Verifier is EssentialContract, IVerifier {
/// @param trusted True if trusted, false otherwise
event ImageTrusted(bytes32 imageId, bool trusted);

/// @dev Emitted when a proof is verified
event ProofVerified(bytes32 metaHash, bytes32 publicInputHash);

error RISC_ZERO_INVALID_IMAGE_ID();
error RISC_ZERO_INVALID_PROOF();

Expand Down Expand Up @@ -80,13 +83,50 @@ contract Risc0Verifier is EssentialContract, IVerifier {

/// @inheritdoc IVerifier
function verifyBatchProof(
ContextV2[] calldata, /*_ctxs*/
TaikoData.TierProof calldata /*_proof*/
ContextV2[] calldata _ctxs,
TaikoData.TierProof calldata _proof
)
external
pure
notImplemented
{ }
{
// Decode will throw if not proper length/encoding
(bytes memory seal, bytes32 blockImageId, bytes32 aggregationImageId) =
abi.decode(_proof.data, (bytes, bytes32, bytes32));

// Check if the aggregation program is trusted
if (!isImageTrusted[aggregationImageId]) {
revert RISC_ZERO_INVALID_IMAGE_ID();
}
// Check if the block proving program is trusted
if (!isImageTrusted[blockImageId]) {
revert RISC_ZERO_INVALID_IMAGE_ID();
smtmfft marked this conversation as resolved.
Show resolved Hide resolved
}

// Collect public inputs
bytes32[] memory public_inputs = new bytes32[](_ctxs.length + 1);
// First public input is the block proving program key
public_inputs[0] = blockImageId;
// All other inputs are the block program public inputs (a single 32 byte value)
for (uint256 i = 0; i < _ctxs.length; i++) {
smtmfft marked this conversation as resolved.
Show resolved Hide resolved
TaikoData.Transition memory tran = _ctxs[i].tran;
address prover = _ctxs[i].prover;
bytes32 metaHash = _ctxs[i].metaHash;
public_inputs[i + 1] = LibPublicInput.hashPublicInputs(
tran, address(this), address(0), prover, metaHash, taikoChainId()
);
emit ProofVerified(metaHash, public_inputs[i + 1]);
}

// journalDigest is the sha256 hash of the hashed public input
bytes32 journalDigest = sha256(abi.encodePacked(public_inputs));

// call risc0 verifier contract
(bool success,) = resolve(LibStrings.B_RISCZERO_GROTH16_VERIFIER, false).staticcall(
abi.encodeCall(IRiscZeroVerifier.verify, (seal, aggregationImageId, journalDigest))
);
if (!success) {
revert RISC_ZERO_INVALID_PROOF();
}
}

function taikoChainId() internal view virtual returns (uint64) {
return ITaikoL1(resolve(LibStrings.B_TAIKO, false)).getConfig().chainId;
Expand Down
45 changes: 40 additions & 5 deletions packages/protocol/contracts/layer1/verifiers/SgxVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,49 @@ contract SgxVerifier is EssentialContract, IVerifier {

/// @inheritdoc IVerifier
function verifyBatchProof(
ContextV2[] calldata, /*_ctxs*/
TaikoData.TierProof calldata /*_proof*/
ContextV2[] calldata _ctxs,
TaikoData.TierProof calldata _proof
)
external
view
notImplemented
onlyFromNamedEither(LibStrings.B_TAIKO, LibStrings.B_TIER_TEE_ANY)
{ }
{
// Size is: 109 bytes
// 4 bytes + 20 bytes + 20 bytes + 65 bytes (signature) = 109
if (_proof.data.length != 109) revert SGX_INVALID_PROOF();

uint32 id = uint32(bytes4(_proof.data[:4]));
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[](_ctxs.length + 2);
smtmfft marked this conversation as resolved.
Show resolved Hide resolved
// First public input is the current instance public key
public_inputs[0] = bytes32(uint256(uint160(oldInstance)));
public_inputs[1] = bytes32(uint256(uint160(newInstance)));
// All other inputs are the block program public inputs (a single 32 byte value)
for (uint256 i = 0; i < _ctxs.length; i++) {
smtmfft marked this conversation as resolved.
Show resolved Hide resolved
// TODO: For now this assumes the new instance public key to remain the same
TaikoData.Transition memory tran = _ctxs[i].tran;
address prover = _ctxs[i].prover;
bytes32 metaHash = _ctxs[i].metaHash;
public_inputs[i + 2] = LibPublicInput.hashPublicInputs(
tran, address(this), newInstance, prover, metaHash, taikoChainId()
smtmfft marked this conversation as resolved.
Show resolved Hide resolved
);
}

bytes32 signatureHash = keccak256(abi.encodePacked(public_inputs));
// Verify the blocks
if (oldInstance != ECDSA.recover(signatureHash, signature)) {
revert SGX_INVALID_PROOF();
}

if (!_isInstanceValid(id, oldInstance)) revert SGX_INVALID_INSTANCE();

if (newInstance != oldInstance && newInstance != address(0)) {
_replaceInstance(id, oldInstance, newInstance);
}
}

function taikoChainId() internal view virtual returns (uint64) {
return ITaikoL1(resolve(LibStrings.B_TAIKO, false)).getConfig().chainId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,64 @@ contract RiscZeroGroth16VerifierTest is TaikoL1TestBase {
graffiti: 0x8008500000000000000000000000000000000000000000000000000000000000
});
}

function test_risc0_verifyBatchProof() public {
vm.startPrank(Emma);

bytes32 aggProofImageId = 0x83e7411adcc296e0a021ff032a868434aa2a519b9d11ad44d11d443832280b44;
bytes32 blkProofImageId = 0x28879b90699846864c97f8f32e1b12aabd8ce13135302345d6ad242fa81ab40d;

// proof generation elf
rv.setImageIdTrusted(aggProofImageId, true);
// proof aggregation elf
rv.setImageIdTrusted(blkProofImageId, true);

vm.startPrank(address(L1));

// Context
IVerifier.ContextV2[] memory ctxs = new IVerifier.ContextV2[](2);
ctxs[0] = IVerifier.ContextV2({
metaHash: 0x207b2833fb6d804612da24d8785b870a19c7a3f25fa4aaeb9799cd442d65b031,
blobHash: 0x01354e8725e60ad91b32ec4ab19158572a0a5b06b2d4d83f6269c9a7d068f49b,
prover: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
msgSender: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
blockId: 393_333,
isContesting: false,
blobUsed: true,
tran: TaikoData.Transition({
parentHash: 0xce519622a374dc014c005d7857de26d952751a9067d3e23ffe14da247aa8a399,
blockHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79,
stateRoot: 0x4203a2fd98d268d272acb24d91e25055a779b443ff3e732f2cee7abcf639b5e9,
graffiti: 0x8008500000000000000000000000000000000000000000000000000000000000
})
});
ctxs[1] = IVerifier.ContextV2({
metaHash: 0x946ba1a9c02fc2f01da49e31cb5be83c118193d0389987c6be616ce76426b44d,
blobHash: 0x01abac8c1fb54f87ff7b0cbf14259b9d5ee7a8de458c587dd6eda43ef8354b4f,
prover: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
msgSender: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
blockId: 393_334,
isContesting: false,
blobUsed: true,
tran: TaikoData.Transition({
parentHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79,
blockHash: 0xc0dad38646ab264be30995b7b7fd02db65e7115126fb52bfad94c0fc9572287c,
stateRoot: 0x222061caab95b6bd0f8dd398088030979efbe56e282cd566f7abd77838558eb9,
graffiti: 0x8008500000000000000000000000000000000000000000000000000000000000
})
});

bytes memory seal =
hex"310fe59810425afc4ed2bae56dfd76e9045f6cd41da30ae8f07a239e86fdb157bf37b0f51b937cb8deccab0d201623d530d0800c208f66dad3f6a38bc1df34408994dec1179209a5f94411e015b20e723512150cfb7e295debeb7ef4f8186cddcf19ba6527ee0d2a0fb8825568682a2fe48e2f73fe9fa052379824751c3bd3f1353f44fe1857e07f5b4801846637b68eafb93aba0c8de8fdfffc76af62a513966f92d9750a977bce0568eb7438fa3497848bfce3e5fd815d9c24b4600e12d0d405d1fd76301ccf27547bddd49a2fa12d1a414f49c2030d0cdf29a87684964a171eefb7e82a5f86acbaacd8cd24d6c3bab06a568f4869087e825ee79237770f23315f3c5c";
// TierProof
TaikoData.TierProof memory proof = TaikoData.TierProof({
tier: 100,
data: abi.encode(seal, blkProofImageId, aggProofImageId)
});

// `verifyProof()`
rv.verifyBatchProof(ctxs, proof);

vm.stopPrank();
}
}
57 changes: 57 additions & 0 deletions packages/protocol/test/layer1/verifiers/SgxVerifier.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,61 @@ contract TestSgxVerifier is TaikoL1TestBase, AttestationBase {

vm.stopPrank();
}

// Test `verifyBatchProof()` happy path
function test_verifyBatchProofs() public {
// setup instances
address newInstance = address(0x6Aa1108c1903E3AeF092FF46E4C506fD3ac567c0);
address[] memory instances = new address[](1);
instances[0] = newInstance;
uint256[] memory ids = sv.addInstances(instances);
console.log("Instance ID: ", ids[0]);

vm.startPrank(address(L1));

uint32 id = uint32(sv.nextInstanceId());

// Context
IVerifier.ContextV2[] memory ctxs = new IVerifier.ContextV2[](2);
ctxs[0] = IVerifier.ContextV2({
metaHash: 0x207b2833fb6d804612da24d8785b870a19c7a3f25fa4aaeb9799cd442d65b031,
blobHash: 0x01354e8725e60ad91b32ec4ab19158572a0a5b06b2d4d83f6269c9a7d068f49b,
prover: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
msgSender: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
blockId: 393_333,
isContesting: false,
blobUsed: true,
tran: TaikoData.Transition({
parentHash: 0xce519622a374dc014c005d7857de26d952751a9067d3e23ffe14da247aa8a399,
blockHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79,
stateRoot: 0x4203a2fd98d268d272acb24d91e25055a779b443ff3e732f2cee7abcf639b5e9,
graffiti: 0x8008500000000000000000000000000000000000000000000000000000000000
})
});
ctxs[1] = IVerifier.ContextV2({
metaHash: 0x946ba1a9c02fc2f01da49e31cb5be83c118193d0389987c6be616ce76426b44d,
blobHash: 0x01abac8c1fb54f87ff7b0cbf14259b9d5ee7a8de458c587dd6eda43ef8354b4f,
prover: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
msgSender: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8,
blockId: 393_334,
isContesting: false,
blobUsed: true,
tran: TaikoData.Transition({
parentHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79,
blockHash: 0xc0dad38646ab264be30995b7b7fd02db65e7115126fb52bfad94c0fc9572287c,
stateRoot: 0x222061caab95b6bd0f8dd398088030979efbe56e282cd566f7abd77838558eb9,
graffiti: 0x8008500000000000000000000000000000000000000000000000000000000000
})
});

// TierProof
bytes memory data =
hex"000000016aa1108c1903e3aef092ff46e4c506fd3ac567c06aa1108c1903e3aef092ff46e4c506fd3ac567c0dda91ea274c36678a0680bae65216b40bd935e646b6364ea669a6de9b58e0cd11e1c1b86765f98ac5a3113fdc08296aa663378e8e2e44cf08db7a4ba6e5f00f21b";
TaikoData.TierProof memory proof = TaikoData.TierProof({ tier: 0, data: data });

// `verifyProof()`
sv.verifyBatchProof(ctxs, proof);

vm.stopPrank();
}
}