Skip to content

Commit

Permalink
Check Proving system ID (#342)
Browse files Browse the repository at this point in the history
* [WIP] Update Aligned to 0.7.0

We must wait until Aligned uploads the release for 0.7.0.

Once it's uploaded we need to add a batcher payment service arg
to the `updateChain` call in the Aligned polling service.

* Update Aligned to 0.7.0

* Update Aligned branch

* Update Aligned and Bridge contracts

* Update Aligned Foundry submodule

* Add Proving system ID commitment check

* Update core lockfile

* Fix ABIs

* Remove unused Solidity error

* Update ABIs
  • Loading branch information
gabrielbosio authored Sep 25, 2024
1 parent f9396d9 commit b9ca11d
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 71 deletions.
42 changes: 25 additions & 17 deletions contract/src/MinaAccountValidation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ pragma solidity ^0.8.12;

import "aligned_layer/contracts/src/core/AlignedLayerServiceManager.sol";

error MinaAccountProvingSystemIdIsNotValid(); // c1872967

contract MinaAccountValidation {
/// @notice The commitment to Mina Account proving system ID.
bytes32 constant PROVING_SYSTEM_ID_COMM = 0xd33e25809fcaa2b6900567812852539da8559dc8b76a7ce3fc5ddd77e8d19a69;

struct AlignedArgs {
bytes32 proofCommitment;
bytes32 provingSystemAuxDataCommitment;
Expand All @@ -22,27 +27,30 @@ contract MinaAccountValidation {
aligned = AlignedLayerServiceManager(_alignedServiceAddr);
}

function validateAccount(
AlignedArgs calldata args
) external view returns (bool) {
function validateAccount(AlignedArgs calldata args) external view returns (bool) {
if (args.provingSystemAuxDataCommitment != PROVING_SYSTEM_ID_COMM) {
revert MinaAccountProvingSystemIdIsNotValid();
}

bytes32 pubInputCommitment = keccak256(args.pubInput);

return
aligned.verifyBatchInclusion(
args.proofCommitment,
pubInputCommitment,
args.provingSystemAuxDataCommitment,
args.proofGeneratorAddr,
args.batchMerkleRoot,
args.merkleProof,
args.verificationDataBatchIndex,
args.batcherPaymentService
);
return aligned.verifyBatchInclusion(
args.proofCommitment,
pubInputCommitment,
args.provingSystemAuxDataCommitment,
args.proofGeneratorAddr,
args.batchMerkleRoot,
args.merkleProof,
args.verificationDataBatchIndex,
args.batcherPaymentService
);
}

function validateAccountAndReturn(
AlignedArgs calldata args
) external view returns (Account memory) {
function validateAccountAndReturn(AlignedArgs calldata args) external view returns (Account memory) {
if (args.provingSystemAuxDataCommitment != PROVING_SYSTEM_ID_COMM) {
revert MinaAccountProvingSystemIdIsNotValid();
}

bytes32 pubInputCommitment = keccak256(args.pubInput);

bool isAccountVerified = aligned.verifyBatchInclusion(
Expand Down
48 changes: 16 additions & 32 deletions contract/src/MinaStateSettlement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ pragma solidity ^0.8.12;

import "aligned_layer/contracts/src/core/AlignedLayerServiceManager.sol";

error MinaProvingSystemIdIsNotValid(bytes32); // f92aa66a
error NewStateIsNotValid(); // 114602f0
error TipStateIsWrong(bytes32 pubInputTipStateHash, bytes32 tipStatehash); // bbd80128
error AccountIsNotValid(bytes32 accountIdHash);

/// @title Mina to Ethereum Bridge's smart contract for verifying and storing a valid state chain.
contract MinaStateSettlement {
/// @notice The commitment to Mina proving system ID.
bytes32 constant PROVING_SYSTEM_ID_COMM = 0xee2a4bc7db81da2b7164e56b3649b1e2a09c58c455b15dabddd9146c7582cebc;

/// @notice The length of the verified state chain (also called the bridge's transition
/// frontier) to store.
uint256 public constant BRIDGE_TRANSITION_FRONTIER_LEN = 16;
Expand Down Expand Up @@ -39,30 +43,19 @@ contract MinaStateSettlement {
}

/// @notice Returns the latest verified chain state hashes.
function getChainStateHashes()
external
view
returns (bytes32[BRIDGE_TRANSITION_FRONTIER_LEN] memory)
{
function getChainStateHashes() external view returns (bytes32[BRIDGE_TRANSITION_FRONTIER_LEN] memory) {
return chainStateHashes;
}

/// @notice Returns the latest verified chain ledger hashes.
function getChainLedgerHashes()
external
view
returns (bytes32[BRIDGE_TRANSITION_FRONTIER_LEN] memory)
{
function getChainLedgerHashes() external view returns (bytes32[BRIDGE_TRANSITION_FRONTIER_LEN] memory) {
return chainLedgerHashes;
}

/// @notice Returns true if this snarked ledger hash was bridged.
function isLedgerVerified(bytes32 ledgerHash) external view returns (bool) {
for (uint256 i = 0; i < BRIDGE_TRANSITION_FRONTIER_LEN; i++) {
if (
chainLedgerHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1 - i] ==
ledgerHash
) {
if (chainLedgerHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1 - i] == ledgerHash) {
return true;
}
}
Expand All @@ -79,19 +72,17 @@ contract MinaStateSettlement {
bytes memory pubInput,
address batcherPaymentService
) external {
if (provingSystemAuxDataCommitment != PROVING_SYSTEM_ID_COMM) {
revert MinaProvingSystemIdIsNotValid(provingSystemAuxDataCommitment);
}

bytes32 pubInputBridgeTipStateHash;
assembly {
pubInputBridgeTipStateHash := mload(add(pubInput, 0x20))
}

if (
pubInputBridgeTipStateHash !=
chainStateHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1]
) {
revert TipStateIsWrong(
pubInputBridgeTipStateHash,
chainStateHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1]
);
if (pubInputBridgeTipStateHash != chainStateHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1]) {
revert TipStateIsWrong(pubInputBridgeTipStateHash, chainStateHashes[BRIDGE_TRANSITION_FRONTIER_LEN - 1]);
}

bytes32 pubInputCommitment = keccak256(pubInput);
Expand All @@ -118,16 +109,9 @@ contract MinaStateSettlement {
// the next BRIDGE_TRANSITION_FRONTIER_LEN sets of 32 bytes are state hashes.
let addr_states := add(pubInput, 64)
// the next BRIDGE_TRANSITION_FRONTIER_LEN sets of 32 bytes are ledger hashes.
let addr_ledgers := add(
addr_states,
mul(32, BRIDGE_TRANSITION_FRONTIER_LEN)
)

for {
let i := 0
} lt(i, BRIDGE_TRANSITION_FRONTIER_LEN) {
i := add(i, 1)
} {
let addr_ledgers := add(addr_states, mul(32, BRIDGE_TRANSITION_FRONTIER_LEN))

for { let i := 0 } lt(i, BRIDGE_TRANSITION_FRONTIER_LEN) { i := add(i, 1) } {
sstore(slot_states, mload(addr_states))
addr_states := add(addr_states, 32)
slot_states := add(slot_states, 1)
Expand Down
6 changes: 3 additions & 3 deletions contract_deployer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use log::{debug, error, info};
use mina_bridge_core::{
eth::{
deploy_mina_account_validation_contract, deploy_mina_bridge_contract,
MinaAccountValidationConstructorArgs, MinaBridgeConstructorArgs, SolStateHash,
MinaAccountValidationConstructorArgs, MinaStateSettlementConstructorArgs, SolStateHash,
},
mina::query_root,
utils::{
Expand Down Expand Up @@ -53,8 +53,8 @@ async fn main() {
_ => todo!(),
};

let bridge_constructor_args = MinaBridgeConstructorArgs::new(aligned_sm_addr, root_hash)
.unwrap_or_else(|err| {
let bridge_constructor_args =
MinaStateSettlementConstructorArgs::new(aligned_sm_addr, root_hash).unwrap_or_else(|err| {
error!("Failed to make constructor args for bridge contract call: {err}");
process::exit(1);
});
Expand Down
2 changes: 1 addition & 1 deletion core/abi/MinaAccountValidation.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion core/abi/MinaStateSettlement.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion core/src/aligned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ pub async fn submit(
proving_system,
proof,
pub_input: Some(pub_input),
verification_key: None,
// Use this instead of `None` to force Aligned to include the commitment to the proving system ID (valid for Aligned 0.7.0)
verification_key: Some(vec![]),
vm_program_code: None,
proof_generator_addr,
};
Expand Down
2 changes: 1 addition & 1 deletion example/app/abi/SudokuValidity.json

Large diffs are not rendered by default.

26 changes: 11 additions & 15 deletions example/eth_contract/src/SudokuValidity.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,23 @@ contract SudokuValidity {
revert InvalidLedger(ledgerHash);
}

MinaAccountValidation.AlignedArgs memory args = MinaAccountValidation
.AlignedArgs(
proofCommitment,
provingSystemAuxDataCommitment,
proofGeneratorAddr,
batchMerkleRoot,
merkleProof,
verificationDataBatchIndex,
pubInput,
batcherPaymentService
);
MinaAccountValidation.AlignedArgs memory args = MinaAccountValidation.AlignedArgs(
proofCommitment,
provingSystemAuxDataCommitment,
proofGeneratorAddr,
batchMerkleRoot,
merkleProof,
verificationDataBatchIndex,
pubInput,
batcherPaymentService
);

if (!accountValidation.validateAccount(args)) {
revert InvalidZkappAccount();
}

bytes calldata encodedAccount = pubInput[32 + 8:];
MinaAccountValidation.Account memory account = abi.decode(
encodedAccount,
(MinaAccountValidation.Account)
);
MinaAccountValidation.Account memory account = abi.decode(encodedAccount, (MinaAccountValidation.Account));

// TODO(xqft): check verification key, it may be a poseidon hash so we should
// need to change it to a keccak hash.
Expand Down

0 comments on commit b9ca11d

Please sign in to comment.