> For the complete documentation index, see [llms.txt](https://docs.nebra.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nebra.one/integrating-with-zkvms/integrating-with-sp1.md).

# Integrating with SP1

SP1 by Succinct Labs is a zkVM technology. It generates STARK proofs but provides tooling for wrapping these STARK proofs with Groth16 or PLONK proofs, so they are more amenable for on-chain verification.&#x20;

The [SP1 Project Template](https://github.com/succinctlabs/sp1-project-template) provided by Succinct Labs provides an end-to-end workflow of how one can verify zkVM proofs on-chain. Roughly the workflow in this repo is:

* A STARK is generated by SP1 which proves the validity of a Fibonacci program written in Rust, which computes the $$n$$th Fibonacci number.
* This STARK proof is wrapped into a PLONK proof via SP1's SDK.
* In the `Fibonacci.sol` smart contract, a `verifyFibonacciProof` function is provided, which takes in the PLONK proof and public inputs and verifies the proof on-chain via a call to a [standardized smart contract](https://github.com/succinctlabs/sp1-contracts/blob/main/contracts/src/v1.2.0/SP1VerifierPlonk.sol) (`SP1VerifierPlonk.sol`) developed by SP1.

NEBRA has created an [UPA-SP1 Project Template](https://github.com/NebraZKP/upa-sp1-project-template) which shows how the above Fibonacci program written in Rust can be aggregated via UPA. Roughly the workflow in this repo is:

* A STARK is generated by SP1 which proves the validity of a Fibonacci program written in Rust, which computes the $$n$$th Fibonacci number (same as above).
* This STARK proof is wrapped into a Groth16 proof via SP1's SDK.
* In the `UpaFibonacci.sol` smart contract,  a `verifyFibonacci` function is provided. However, unlike the workflow above, the Groth16 proof is *not* submitted to this contract. Rather, this function *only* takes in the public inputs and calls into the `UPAVerfier` contract to check whether a Groth16 proof corresponding to these public inputs and the SP1 Groth16 circuit have been aggregated by the UPA system.
* A [shell script](https://github.com/NebraZKP/upa-sp1-project-template/blob/main/upa/scripts/upa_sp1) showing the end-end-end flow is provided. In this script:
  * A `UPAVerifier` contract is deployed to a local hardhat node.
  * The SP1 Groth16 proof corresponding to the Fibonacci circuit, along with another Groth16 proof is submitted to the `UPAVerifier` contract.
  * UPA's`dev-aggregator` dev tool, which mimics our actual aggregator, is used to aggregate these two proofs and submit the result on-chain.
  * The `UPAFibonacci` contract is called to check whether the SP1 Groth16 Fibonacci proof has been verified.

In general, for apps looking to integrate UPA with SP1, the workflow would be as follows:

* Use SP1 SDK to wrap your SP1 STARK proof and generate a Groth16 proof.
* Using UPA's CLI tool or SDK, parse the Groth16 proof data into UPA proof file format.
* Use UPA's CLI tool or SDK to submit the proof to `UPAVerifier` contract.
* Wait for proof to be aggregated and then use the result in business logic of the app.
