🙌
Plonky2というゼロ知識証明アルゴリズムで実装されているEVMの証明をチラ見してみる
はじめに
この記事はRust Advent Calendar 2022の19日目の記事です。
本当はCosmWASMで残高を秘匿するコインを作って紹介しようと思ったのですが、実装が間に合いませんでした 🙏
Rustと個人的な興味であるクリプトがマッチしていそうな分野の「ゼロ知識証明」の Plonky2
のEVMについてチラ見していきたいと思います。
投稿が遅れてしまって申し訳ないです。
ゼロ知識証明とは?
ゼロ知識証明とは、秘密を知っていることを秘密を教えることなく、第三者に秘密を知っていると証明できる仕組みのことです。
ここではあまり深入りしませんが、zkRollupを作る上で大切な特徴があります。それは、大量の計算を正しく行ったことを証拠を見るだけで検証できるということです。 zkRollupの回路内で計算してること
以降ZKPとします。
EthereumとEVMとは?
Ethereumはスマートコントラクトを実装しているブロックチェーンの1つです。
EVMは、Ethereumに採用されているVMのことです。
Plonky2とは?
mir-protocolが開発した再帰的なZKPを高速化するツールです。
シンプルな送金txについて見てみる
シンプルな新しいアドレスへの送金テストがあったので、そちらに日本語で適当にコメントを入れていきます。
/// Test a simple token transfer to a new address.
#[test]
fn test_simple_transfer() -> anyhow::Result<()> {
init_logger();
let all_stark = AllStark::<F, D>::default();
let config = StarkConfig::standard_fast_config();
// アドレスを定義しています。
let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23");
let to = hex!("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0");
// keccakとはEthereumでよく使われるハッシュ関数です。
let sender_state_key = keccak(sender);
let to_state_key = keccak(to);
let sender_nibbles = Nibbles::from(sender_state_key);
let to_nibbles = Nibbles::from(to_state_key);
let value = U256::from(100u32);
// アカウントを初期化しています。
let sender_account_before = AccountRlp {
nonce: 5.into(),
balance: eth_to_wei(100_000.into()),
storage_root: PartialTrie::Empty.calc_hash(),
// code_hashが空ってことはEOAを表しているのかも
code_hash: keccak([]),
};
// EthereumではBitcoinのようなシンプルなMerkle Treeではなく、Merkle Patricia Trieという木構造が利用されています。
// https://docs.rs/eth_trie_utils/0.3.0/eth_trie_utils/partial_trie/enum.PartialTrie.html
let state_trie_before = PartialTrie::Leaf {
nibbles: sender_nibbles,
// RLPエンコードとは、Recursive Length Prefixの略で、Ethereumでよく目にします。
// >RLPは高度に最小化したシリアライゼーションフォーマットで、ネストされたByte配列を保存する目的のためにある。
// >protobufやBSONなどとは違って、BooleanやFloat、DoubleやIntegerさえ定義しない
// だそうです。
value: rlp::encode(&sender_account_before).to_vec(),
};
let tries_before = TrieInputs {
state_trie: state_trie_before,
transactions_trie: PartialTrie::Empty,
receipts_trie: PartialTrie::Empty,
storage_tries: vec![],
};
// Generated using a little py-evm script. py-evmで事前にスクリプトを書いたようです。
let txn = hex!("f861050a8255f094a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0648242421ba02c89eb757d9deeb1f5b3859a9d4d679951ef610ac47ad4608dc142beb1b7e313a05af7e9fbab825455d36c36c7f4cfcafbeafa9a77bdff936b52afb36d4fe4bcdd");
let block_metadata = BlockMetadata::default();
let inputs = GenerationInputs {
signed_txns: vec![txn.to_vec()],
tries: tries_before,
contract_code: HashMap::new(),
block_metadata,
};
let mut timing = TimingTree::new("prove", log::Level::Debug);
// ZKのprove(証明)をここでやっています。EVMが正しい挙動をしているという証明をしています。
let proof = prove::<F, C, D>(&all_stark, &config, inputs, &mut timing)?;
timing.filter(Duration::from_millis(100)).print();
// txの後で期待する動作を定義しています。
let expected_state_trie_after = {
// 送金したので、残高が減っている
let sender_account_after = AccountRlp {
balance: sender_account_before.balance - value, // TODO: Also subtract gas_used * price. まだガスプライスの計算は行なっていないようでうs。
// nonce: sender_account_before.nonce + 1, // TODO: まだnonceがうまく動いていないようでうs。
..sender_account_before
};
let to_account_after = AccountRlp {
balance: value,
..AccountRlp::default()
};
let mut children = std::array::from_fn(|_| PartialTrie::Empty.into());
children[sender_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
nibbles: sender_nibbles.truncate_n_nibbles_front(1),
value: rlp::encode(&sender_account_after).to_vec(),
}
.into();
children[to_nibbles.get_nibble(0) as usize] = PartialTrie::Leaf {
nibbles: to_nibbles.truncate_n_nibbles_front(1),
value: rlp::encode(&to_account_after).to_vec(),
}
.into();
PartialTrie::Branch {
children,
value: vec![],
}
};
// ZK Proofのstate rootと素で計算した送金後のステートルートを比較する
assert_eq!(
proof.public_values.trie_roots_after.state_root,
expected_state_trie_after.calc_hash()
);
// proof(証拠)のverify(検証)もやっておく
verify_proof(all_stark, proof, &config)
}
まとめ
駆け足でしたが、ざっくり証明の過程と証明について見れました。
Proveの中身を見ると大変なことになりそうですね。
明日は@namn1125さんです、お願いします!
no plan株式会社について
- no plan株式会社は、ブロックチェーン技術、Webサイト開発、ネイティブアプリ開発、チーム育成、などWebサービス全般の開発から運用や教育、支援などを行っています。よくわからない、ふわふわしたノープラン状態でも大丈夫!ご一緒にプランを立てていきましょう!
- no plan株式会社について
- no plan株式会社 | ブロックチェーン実績
- no plan株式会社 | ブログ一覧
Discussion