Succinct SP1 Integration

Overview

In a nutshell, for each newly generated Nubit DA block, we have its correctness proved by zero-knowledge (ZK).

How is this possibly done?

Succinct provides the light service that proves each newly generated Nubit block and submits the proof to a contract. Hence, each block generation is proved and the proof is publicly verifiable. This further enhances our Nubit DA chain, providing a more trustless and secure DA with strong data integrity and unforgeability.

The underlying technique is the SP1 zero-knowledge virtual machine (zkVM), developed by the Succinct team.

Why SP1?

Different from application-specific zero-knowledge circuits, SP1 provides general-purpose zero-knowledge. Namely, for any application logic that can be programmed via canonical programming languages (like C, Rust, etc.), its compiled bytecodes could be taken as inputs to SP1, and has its ZK circuit generated instantly and autonomously. Powered by this primitive, customizability, flexibility, and convenience are brought about to the web3 ZK ecosystem with strong security and trustlessness. In short, compared with composing ZK circuits manually, proving block transitions by SP1 is merited for the following benefits.

(1) Easier circuits.

SP1 enables easier ZK circuit composing. Manually writing the ZK circuit is costly and incurs an excessive workload even for professionals. By leveraging SP1, logic to be verified can be programmed in traditional programming languages without involving any domain-specific language (DSL) or ZK-specific library.

(2) Easier updating and testing.

Despite the difficulty, we could have composed the ZK circuit manually, however, it is hard to update or test the logic even if the underlying verification logic is slightly changed. The hardness originates from the nature of existing ZK DSLs. However, by SP1, we could easily update the logic by revising a traditional code block. Also, we are allowed to compile the same code block into executable files (simultaneously into ZK circuits) and test the revised logic with classical code testing techniques.

(3) Strong security.

Merited from the soundness property of the underlying ZK proofs, nobody could forge a valid proof for a “wrong” block. This means that, as long as valid proof is obtained and verified, the block could be viewed as correct. This further guarantees the trustlessness and security of our Nubit DA network.

What is proved?

Based on this technique, the ZK circuit generated from SP1 verifies the following logic for each block transition. To facilitate descriptions, for each block transition, we refer to the earlier block as the pre-block and the latter as the post-block.

(1) Validator set.

Validators are the nodes operating the consensus scheme, which is the kernel of secure chain growth and liveness for any blockchain. A correct validator set of the post-block should be delivered to the proof machine as a witness. This validator set could only differ from the pre-block one slightly according to the set switchover rule.

(2) Block consistency.

The block transition should be semantically correct. For instance, the block height of the post-block should be greater than the pre-block by one. Also, the pre-block, which is inputted to the proof machine, should be verified as a valid historical block to guarantee unforgeability.

(3) Commitment verification.

Finally and most importantly, the commitments, signatures, and other auxiliary block information should be verified against the aforementioned validator public key set. This allows for block verifications and further provides non-repudiation in case of validator misbehavior (extremely unlikely to happen though).

Wait.. At What Cost?

Seemingly, this is a large ZK circuit to prove. However, the proof is extremely friendly to lightweight clients! Technically, SP1 proves by STARK and has the STARK proof wrapped by SNARKs with a shorter proof size. Hence, our ZK not only enjoys the efficiency of STARK proof generation but also has an extremely short proof size and fast proof verification. As a result, proof generation is efficient and the verification only involves constant computation on a proof with a short and constant size.

Layer Two Applications Joining Us

The block transition proofs, delivered to layer-1 smart contracts in the settlement phase, can be efficiently verified by lightweight users via triggering a verification smart contract and can be aggregated by recursive proofs. The proofs provide trustless and safe block headers for all users, even lightweight clients. Along with the data inclusion proofs, whose verification takes block headers as public inputs, the Nubit DA layer offers completely trustless and secure data retrieval for any node. This means that, with our proofs for each block transition, layer-2 application users are allowed to safely obtain Nubit DA block data without trusting any third-party data provider.

Thereby, layer-2 project teams no longer have to maintain their data. They only need to send data to Nubit DA and users can obtain the data safely and verify the data by layer-1 smart contracts without assuming the honesty of any node.


Run Integration Demo

Environment Setup

Install Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup install nightly
sudo apt install pkg-config libssl-dev -y

Install Foundry

curl -L https://foundry.paradigm.xyz/ | bash
source ~/.bashrc
foundryup

Install SP1

curl -L https://sp1.succinct.xyz | bash
source ~/.bashrc
sp1up

Verify Installation

rustup toolchain list

Clone the Repository

Clone the Repository

git clone https://github.com/succinctlabs/sp1-tendermint-example.git
cd sp1-tendermint-example

Test the Program

Build Binaries

cd operator
cargo build --bin operator --release
cargo build --bin genesis --release
cargo build --bin fixture --release

Run Fixtures

cd ../operator
RUST_LOG=debug TENDERMINT_RPC_URL="https://validator.nubit-alphatestnet-1.com:26657" ./target/release/fixture --trusted-block 500 --target-block 1000

Run Operator

Export Environment Variables

export PRIVATE_KEY=bb372db0244ff8142c36e4846f19f766b7a917715d9d02e67d74e6194a064d59
export RPC_URL=https://go.getblock.io/a186d4a53dbb4dfab0133761d3070a53
export ETHERSCAN_API_KEY=SDTDTCIACR6MTJV8QRPJBXAAT7BXVW3QB2
export CHAIN_ID=11155111
export TENDERMINT_RPC_URL="https://validator.nubit-alphatestnet-1.com:26657"

Generate Genesis Data

TENDERMINT_RPC_URL=$TENDERMINT_RPC_URL ./target/release/genesis

Export Generated Data

export VKEY_DIGEST=0x00946b4ac6eca4af8bbe4331568ddac266d0fa4720f0a4aa5926976bbabe41cb
export TRUSTED_HEIGHT=70023
export TRUSTED_HEADER_HASH=9DAF83BCCB37AB31A1095D5865E5F973589BF2235D116E8B4EE1FD3D9F8708E6

Deploy Contract

Deploy and Verify Contract

cd ../contracts
forge script script/SP1Tendermint.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --etherscan-api-key $ETHERSCAN_API_KEY --broadcast --verify

Export Contract Address

export CONTRACT_ADDRESS=0xb9a9F4a2c20a86E1c7Ef0251afe0b914CE8dFF22

Run Operator

Start Operator

cd ../operator
RUST_LOG=debug RUST_BACKTRACE=1 TENDERMINT_RPC_URL=$TENDERMINT_RPC_URL ./target/release/operator

Check logs

Logs should be displayed, indicating that proofs are being generated for newly assembled blocks.

Last updated