Skip to content

Remove Tree From Verifier Input #96

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 10 additions & 9 deletions contracts/src/ProtocolAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ contract ProtocolAdapter is IProtocolAdapter, ReentrancyGuardTransient, Commitme

uint256 nResources = action.logicVerifierInputs.length;
for (uint256 j = 0; j < nResources; ++j) {
Logic.Instance calldata instance = action.logicVerifierInputs[j].instance;
Logic.VerifierInput calldata instance = action.logicVerifierInputs[j];

if (instance.isConsumed) {
_checkNullifierNonExistence(instance.tag);
Expand Down Expand Up @@ -217,24 +217,25 @@ contract ProtocolAdapter is IProtocolAdapter, ReentrancyGuardTransient, Commitme

bytes32[] memory actionTags = new bytes32[](nResources);
for (uint256 j = 0; j < nResources; ++j) {
actionTags[j] = action.logicVerifierInputs[j].instance.tag;
actionTags[j] = action.logicVerifierInputs[j].tag;
}
bytes32 computedActionTreeRoot = MerkleTree.computeRoot(actionTags, _ACTION_TAG_TREE_DEPTH);

for (uint256 j = 0; j < nResources; ++j) {
Logic.VerifierInput calldata input = action.logicVerifierInputs[j];

// Check root consistency
if (input.instance.actionTreeRoot != computedActionTreeRoot) {
revert RootMismatch({expected: computedActionTreeRoot, actual: input.instance.actionTreeRoot});
}

// Check the compliance proof
// slither-disable-next-line calls-loop
_TRUSTED_RISC_ZERO_VERIFIER_ROUTER.verify({
seal: input.proof,
imageId: input.verifyingKey,
journalDigest: input.instance.toJournalDigest()
journalDigest: Logic.Instance({
tag: input.tag,
isConsumed: input.isConsumed,
actionTreeRoot: computedActionTreeRoot,
ciphertext: input.ciphertext,
appData: input.appData
}).toJournalDigest()
});
}
}
Expand Down Expand Up @@ -278,7 +279,7 @@ contract ProtocolAdapter is IProtocolAdapter, ReentrancyGuardTransient, Commitme

// Lookup the first appData entry.
bytes32 actualAppDataHash =
keccak256(abi.encode(action.logicVerifierInputs.lookup(carrier.commitment()).instance.appData[0]));
keccak256(abi.encode(action.logicVerifierInputs.lookup(carrier.commitment()).appData[0]));

if (actualAppDataHash != expectedAppDataHash) {
revert CalldataCarrierAppDataMismatch({actual: actualAppDataHash, expected: expectedAppDataHash});
Expand Down
7 changes: 5 additions & 2 deletions contracts/src/proving/Logic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ library Logic {
// in another circuit and can be hard-coded similar to the compliance proof verifying key.
struct VerifierInput {
bytes proof;
Instance instance;
bytes32 tag;
bool isConsumed;
bytes ciphertext;
ExpirableBlob[] appData;
bytes32 verifyingKey;
}

Expand All @@ -61,7 +64,7 @@ library Logic {
{
uint256 len = list.length;
for (uint256 i = 0; i < len; ++i) {
if (list[i].instance.tag == tag) {
if (list[i].tag == tag) {
return foundElement = list[i];
}
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/Deployment.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ contract ProtocolAdapterTest is Test {
}

function test_run_deploys_deterministically() public view {
assertEq(address(_pa), 0x2D5881c30342F5325D166bF65855cB3B662AA015);
assertEq(address(_pa), 0xF6a8C418541F8738A6eCf57312DA0C492d50AA22);
}
}
8 changes: 4 additions & 4 deletions contracts/test/ProtocolAdapter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,16 @@ contract ProtocolAdapterTest is Test {

Transaction memory txn = Example.transaction();
vm.expectEmit(address(_pa));
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[0].instance.appData[0]);
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[0].appData[0]);

vm.expectEmit(address(_pa));
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[0].instance.appData[1]);
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[0].appData[1]);

vm.expectEmit(address(_pa));
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[1].instance.appData[0]);
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[1].appData[0]);

vm.expectEmit(address(_pa));
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[1].instance.appData[1]);
emit IProtocolAdapter.Blob(txn.actions[0].logicVerifierInputs[1].appData[1]);

_pa.execute(txn);
}
Expand Down
6 changes: 5 additions & 1 deletion contracts/test/mocks/Example.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ library Example {
}

function logicVerifierInput(bool isConsumed) internal pure returns (Logic.VerifierInput memory input) {
Logic.Instance memory instance = logicInstance(isConsumed);
input = Logic.VerifierInput({
proof: isConsumed ? _CONSUMED_LOGIC_PROOF : _CREATED_LOGIC_PROOF,
instance: logicInstance(isConsumed),
tag: instance.tag,
isConsumed: instance.isConsumed,
ciphertext: instance.ciphertext,
appData: instance.appData,
verifyingKey: isConsumed ? _CONSUMED_LOGIC_REF : _CREATED_LOGIC_REF
});
}
Expand Down
12 changes: 8 additions & 4 deletions contracts/test/proofs/LogicProof.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ contract LogicProofTest is Test {
}

function test_verify_example_logic_proof_consumed() public {
Logic.VerifierInput memory input = Example.logicVerifierInput({isConsumed: true});
Logic.Instance memory instance = Example.logicInstance({isConsumed: true});

bytes32 journalDigest = instance.toJournalDigest();

bytes32 journalDigest = input.instance.toJournalDigest();
Logic.VerifierInput memory input = Example.logicVerifierInput({isConsumed: true});

// TODO! Update example to a non-vulnerable version.
address riscZeroEmergencyStop = address(_sepoliaVerifierRouter.getVerifier(bytes4(input.proof)));
Expand All @@ -37,9 +39,11 @@ contract LogicProofTest is Test {
}

function test_verify_example_logic_proof_created() public {
Logic.VerifierInput memory input = Example.logicVerifierInput({isConsumed: false});
Logic.Instance memory instance = Example.logicInstance({isConsumed: false});

bytes32 journalDigest = instance.toJournalDigest();

bytes32 journalDigest = input.instance.toJournalDigest();
Logic.VerifierInput memory input = Example.logicVerifierInput({isConsumed: false});

// TODO! Update example to a non-vulnerable version.
address riscZeroEmergencyStop = address(_sepoliaVerifierRouter.getVerifier(bytes4(input.proof)));
Expand Down
Loading