Skip to content
Merged
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
24 changes: 0 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ members = [
"circuits/state-chain-proof/host",
"circuits/watchtower-proof/host",
"circuits/operator-proof/host",
"circuits/operator-wrapper-proof/host",
"circuits/proof-builder",
]
default-members = ["node"]
Expand Down Expand Up @@ -127,7 +126,6 @@ state-chain = { path = "crates/state-chain" }
verifier = { path = "crates/verifier" }
state-chain-proof = { path = "circuits/state-chain-proof/host" }
operator-proof = { path = "circuits/operator-proof/host" }
operator-wrapper-proof = { path = "circuits/operator-wrapper-proof/host" }
watchtower-proof = { path = "circuits/watchtower-proof/host" }
proof-builder = { path = "circuits/proof-builder" }

Expand Down
9 changes: 2 additions & 7 deletions circuits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,18 +242,13 @@ export WATCHTOWER_CHALLENGE_INIT_TXID="e7723e03ac97172cf033e40d4b9d9c0e22efa7a41
RUST_LOG=info cargo run --package operator-proof --bin operator-proof -r -- --output "data/operator-proof/output.bin"
```

Then wrap the operator proof before the operator sends assert-commit. The Challenge script validates
the wrapper proof public inputs:

```
bash run-operator-wrapper-proof.sh "data/operator-proof/output.bin" "data/operator-wrapper-proof/output.bin"
```
The operator proof is consumed directly by the Assert flow. BABE setup binds its static public
input, while the dynamic public input is committed after the watchtower challenge set is known.

* latest-sequencer-commit-txid: the latest publisher's commitment Bitcoin transaction id
* header-chain-input-proof: the header chain's proof, input and vk.
* commit-chain-input-proof: the commit chain's proof, input and vk.
* included-watchtower: a 256-bit bitmask; each bit flags a valid watchtower inside operator proof.
* operator-wrapper-proof: wraps operator proof and exposes `operator_vk_hash_raw`, raw 16-byte `graph_id`, and `genesis_sequencer_commit_txid` as public inputs for Challenge.
* execution-layer-block-number: the block number that including `proceedWithdraw`(Peg-out) transaction of GOAT Network's execution layer(Geth).
* watchtower-challenge-info: list of watchtower's challenge transaction id and compressed public key, i.e: [wachtower_info.json](./data/watchtower/watchtower_info.json).
* watchtower-challenge-init-txid: the watchtower challenge init transaction id in GOAT's BitVM2 graph.
6 changes: 2 additions & 4 deletions circuits/operator-proof/guest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub fn main() {
println!("read operator commit txn");
let operator_latest_sequencer_commit_txn: Transaction = zkm_zkvm::io::read(); // private inputs
let latest_sequencer_commit_txid = operator_latest_sequencer_commit_txn.compute_txid(); // public input

// https://github.com/KSlashh/BitVM/blob/v2/goat/src/transactions/watchtower_challenge.rs#L128
let watchtower_challenge_txns: Vec<Transaction> = zkm_zkvm::io::read();
let watchtower_challenge_txn_pubkey: Vec<bitcoin::secp256k1::PublicKey> = zkm_zkvm::io::read();
Expand All @@ -29,9 +30,8 @@ pub fn main() {
let operator_state_chain: StateChainCircuitInput = zkm_zkvm::io::read();
let spv_ss_commit: SPV = zkm_zkvm::io::read();
let operator_committed_blockhash: [u8; 32] = zkm_zkvm::io::read();
let actual_operator_vk_hash: [u8; 32] = zkm_zkvm::io::read();

let (btc_best_block_hash, constant, included_watchtowers, operator_vk_hash) =
let (btc_best_block_hash, constant, included_watchtowers) =
bitcoin_light_client_circuit::propose_longest_chain(
included_watchtowers,
graph_id,
Expand All @@ -46,11 +46,9 @@ pub fn main() {
operator_state_chain,
spv_ss_commit,
operator_committed_blockhash,
actual_operator_vk_hash,
);

zkm_zkvm::io::commit(&btc_best_block_hash);
zkm_zkvm::io::commit(&constant);
zkm_zkvm::io::commit(&included_watchtowers);
zkm_zkvm::io::commit(&operator_vk_hash);
}
9 changes: 1 addition & 8 deletions circuits/operator-proof/host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bitcoin::{
hashes::Hash,
secp256k1::{PublicKey, XOnlyPublicKey},
};
use bitcoin_light_client_circuit::{build_spv, zkm_vk_hash_to_raw};
use bitcoin_light_client_circuit::build_spv;
use bitcoin_script::script;
use borsh::BorshDeserialize;
use clap::Parser;
Expand Down Expand Up @@ -400,9 +400,6 @@ impl ProofBuilder for OperatorProofBuilder {
&bitcoin_block_headers,
);

let actual_operator_vk_hash = zkm_vk_hash_to_raw(self.verifying_key.bytes32().as_bytes())
.map_err(anyhow::Error::msg)?;

// Generate the proofs
let (proof, cycles, proving_time) = tracing::info_span!("generate proof").in_scope(
|| -> anyhow::Result<(ZKMProofWithPublicValues, u64, f32)> {
Expand All @@ -426,7 +423,6 @@ impl ProofBuilder for OperatorProofBuilder {
stdin.write(&state_chain_input);
stdin.write(&spv_ss_commit);
stdin.write(&operator_committed_blockhash.to_byte_array());
stdin.write(&actual_operator_vk_hash);

let elf_id = if ELF_ID.get().is_none() {
ELF_ID
Expand Down Expand Up @@ -494,11 +490,8 @@ mod tests {
let proof: ZKMProofWithPublicValues = bincode::deserialize(&proof_bytes).unwrap();

let vk_hash = String::from_utf8(vk_bytes).unwrap();
let operator_vk_hash =
bitcoin_light_client_circuit::zkm_vk_hash_to_raw(vk_hash.as_bytes()).unwrap();
let a = bitcoin_light_client_circuit::decode_operator_public_outputs(
proof.public_values.as_slice(),
operator_vk_hash,
)
.unwrap();
println!(
Expand Down
Loading