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

Check Proving system ID #342

Merged
merged 13 commits into from
Sep 25, 2024
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