Skip to content

Commit

Permalink
kinda sorta compiles
Browse files Browse the repository at this point in the history
  • Loading branch information
mattstam committed Dec 11, 2024
1 parent 8ff3262 commit 1dbb0d4
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 36 deletions.
3 changes: 2 additions & 1 deletion crates/sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
//! Visit the [Getting Started](https://succinctlabs.github.io/sp1/getting-started.html) section
//! in the official SP1 documentation for a quick start guide.
mod client;
pub mod client;
mod local;
mod mode;
mod network;
mod opts;
mod prover;
mod request;
mod verify;

pub mod action;
pub mod artifacts;
Expand Down
11 changes: 5 additions & 6 deletions crates/sdk/src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use crate::proof::SP1ProofWithPublicValues;
use crate::prover::Prover;
use crate::provers::SP1VerificationError;
use crate::request::ProofRequest;
use crate::verify;

use anyhow::Result;
use async_trait::async_trait;
use sp1_core_executor::{ExecutionReport, SP1Context};
use sp1_core_machine::io::SP1Stdin;
use sp1_prover::components::DefaultProverComponents;
use sp1_prover::{SP1Prover, SP1ProvingKey, SP1VerifyingKey};
use sp1_prover::{SP1Prover, SP1ProvingKey, SP1VerifyingKey, SP1_CIRCUIT_VERSION};
use std::future::{Future, IntoFuture};
use std::pin::Pin;

Expand Down Expand Up @@ -78,8 +79,8 @@ impl<'a> LocalProofRequest<'a> {

#[async_trait]
impl Prover for LocalProver {
async fn setup(&self, elf: &[u8]) -> Result<(SP1ProvingKey, SP1VerifyingKey)> {
self.prover.setup(elf).map_err(anyhow::Error::from)
async fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
self.prover.setup(elf)
}

async fn execute(&self, elf: &[u8], stdin: SP1Stdin) -> Result<ExecutionReport> {
Expand Down Expand Up @@ -113,9 +114,7 @@ impl Prover for LocalProver {
proof: &SP1ProofWithPublicValues,
vk: &SP1VerifyingKey,
) -> Result<(), SP1VerificationError> {
self.prover
.verify_proof(proof, vk)
.map_err(|e| SP1VerificationError::VerificationFailed(e.to_string()))
verify::verify(&self.prover, SP1_CIRCUIT_VERSION, proof, vk)
}
}

Expand Down
17 changes: 16 additions & 1 deletion crates/sdk/src/network-v2/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use tonic::{
use sp1_core_machine::io::SP1Stdin;
use sp1_prover::{HashableKey, SP1VerifyingKey};

use crate::mode::Mode;
use crate::network_v2::proto::artifact::{
artifact_store_client::ArtifactStoreClient, CreateArtifactRequest,
};
Expand All @@ -34,6 +35,11 @@ pub struct NetworkClient {
signer: PrivateKeySigner,
http: HttpClientWithMiddleware,
rpc_url: String,
pub mode: Mode,
pub timeout_secs: Option<u64>,
pub cycle_limit: Option<u64>,
pub skip_simulation: bool,
pub fulfillment_strategy: Option<FulfillmentStrategy>,
}

impl NetworkClient {
Expand All @@ -47,7 +53,16 @@ impl NetworkClient {
.build()
.unwrap();

Self { signer, http: http_client.into(), rpc_url: DEFAULT_PROVER_NETWORK_RPC.to_string() }
Self {
signer,
http: http_client.into(),
rpc_url: DEFAULT_PROVER_NETWORK_RPC.to_string(),
mode: Mode::default(),
timeout_secs: None,
cycle_limit: None,
skip_simulation: false,
fulfillment_strategy: None,
}
}

/// Update the RPC URL for the client.
Expand Down
45 changes: 28 additions & 17 deletions crates/sdk/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::request::ProofRequest;
use crate::network_v2::FulfillmentStrategy;
use crate::network_v2::DEFAULT_PROVER_NETWORK_RPC;
use crate::network_v2::{Error, RequestId, VerifyingKeyHash};
use crate::verify;
use crate::{network_v2::NetworkClient, proof::SP1ProofWithPublicValues};

pub struct NetworkProver {
Expand All @@ -38,7 +39,7 @@ impl NetworkProver {
}

pub fn with_mode(mut self, mode: Mode) -> Self {
self.network_client.mode = mode;
self.network_client.mode = mode.into();
self
}

Expand Down Expand Up @@ -104,7 +105,11 @@ impl NetworkProver {
todo!()
}

pub fn prove_with_options(&self, pk: &SP1ProvingKey, stdin: SP1Stdin) -> NetworkProofRequest {
pub fn prove_with_options<'a>(
&'a self,
pk: &'a SP1ProvingKey,
stdin: SP1Stdin,
) -> NetworkProofRequest<'a> {
NetworkProofRequest::new(self, pk, stdin)
}

Expand All @@ -130,22 +135,22 @@ impl NetworkProverBuilder {

pub fn build(self) -> NetworkProver {
NetworkProver::new(
self.rpc_url.unwrap_or_default(DEFAULT_PROVER_NETWORK_RPC),
self.rpc_url.unwrap_or_else(|| DEFAULT_PROVER_NETWORK_RPC.to_string()),
self.private_key.expect("private key is required"),
)
}
}

pub struct NetworkProofRequest<'a> {
pub prover: &'a NetworkProver,
pub pk: &'a SP1ProvingKey,
pub stdin: SP1Stdin,
pub version: String,
pub mode: Mode,
pub fulfillment_strategy: Option<FulfillmentStrategy>,
pub timeout_sec: Option<u64>,
pub cycle_limit: Option<u64>,
pub skip_simulation: bool,
prover: &'a NetworkProver,
pk: &'a SP1ProvingKey,
stdin: SP1Stdin,
version: String,
mode: Mode,
fulfillment_strategy: Option<FulfillmentStrategy>,
timeout_sec: Option<u64>,
cycle_limit: Option<u64>,
skip_simulation: bool,
}

impl<'a> NetworkProofRequest<'a> {
Expand Down Expand Up @@ -178,6 +183,11 @@ impl<'a> NetworkProofRequest<'a> {
self
}

pub fn with_cycle_limit(mut self, cycle_limit: u64) -> Self {
self.cycle_limit = Some(cycle_limit);
self
}

pub async fn run(self) -> Result<SP1ProofWithPublicValues> {
// Ensure the program is registered
let vk_hash = self.prover.register_program(&self.pk.vk, &self.pk.elf).await?;
Expand Down Expand Up @@ -228,8 +238,8 @@ impl<'a> IntoFuture for NetworkProofRequest<'a> {

#[async_trait]
impl Prover for NetworkProver {
async fn setup(&self, elf: &[u8]) -> Result<(SP1ProvingKey, SP1VerifyingKey)> {
self.prover.setup(elf).map_err(anyhow::Error::from)
async fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
self.prover.setup(elf)
}

async fn execute(&self, elf: &[u8], stdin: SP1Stdin) -> Result<ExecutionReport> {
Expand All @@ -245,7 +255,8 @@ impl Prover for NetworkProver {
) -> Result<SP1ProofWithPublicValues> {
let request = NetworkProofRequest::new(self, pk, stdin.clone())
.with_mode(opts.mode)
.with_timeout(opts.timeout);
.with_timeout(opts.timeout)
.with_cycle_limit(opts.cycle_limit);
request.run().await
}

Expand All @@ -265,13 +276,13 @@ impl Prover for NetworkProver {
proof: &SP1ProofWithPublicValues,
vk: &SP1VerifyingKey,
) -> Result<(), SP1VerificationError> {
self.prover.verify(proof, vk)
verify::verify(&self.prover, SP1_CIRCUIT_VERSION, proof, vk)
}
}

#[cfg(feature = "blocking")]
impl ProofRequest for NetworkProofRequest<'_> {
async fn run(self) -> Result<SP1ProofWithPublicValues> {
self.prover.prove_with_options(&self.pk, self.stdin).await
self.prover.prove_with_options(&self.pk, &self.stdin, &self.opts).await
}
}
2 changes: 1 addition & 1 deletion crates/sdk/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{opts::ProofOpts, proof::SP1ProofWithPublicValues, provers::SP1Verifi

#[async_trait]
pub trait Prover: Send + Sync {
async fn setup(&self, elf: &[u8]) -> Result<(SP1ProvingKey, SP1VerifyingKey)>;
async fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey);

async fn execute(&self, elf: &[u8], stdin: SP1Stdin) -> Result<ExecutionReport>;

Expand Down
24 changes: 16 additions & 8 deletions crates/sdk/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,25 @@ pub trait ProofRequest {
) -> Pin<Box<dyn Future<Output = Result<SP1ProofWithPublicValues>> + Send + 'static>>;
}

pub struct DynProofRequest<'a, 'b> {
pub struct DynProofRequest<'a, 'b: 'a> {
prover: &'a dyn Prover,
elf: &'b [u8],
pk: SP1ProvingKey,
stdin: SP1Stdin,
opts: ProofOpts,
}

impl<'a, 'b> DynProofRequest<'a, 'b> {
impl<'a, 'b: 'a> DynProofRequest<'a, 'b> {
pub fn new(
prover: &'a dyn Prover,
elf: &'b [u8],
pk: SP1ProvingKey,
stdin: SP1Stdin,
opts: ProofOpts,
) -> Self {
Self { prover, elf, pk, stdin, opts }
}

pub fn proof_type(mut self, mode: Mode) -> Self {
self.opts.mode = mode;
self
Expand All @@ -37,19 +47,17 @@ impl<'a, 'b> DynProofRequest<'a, 'b> {
self.opts.cycle_limit = cycle_limit;
self
}
}

impl<'a, 'b> DynProofRequest<'a, 'b> {
fn run(self) -> Result<SP1ProofWithPublicValues> {
self.prover.prove_with_options(self.elf, self.pk, self.stdin, self.opts)
async fn run(self) -> Result<SP1ProofWithPublicValues> {
self.prover.prove_with_options(&self.pk, &self.stdin, &self.opts).await
}
}

impl<'a, 'b> IntoFuture for DynProofRequest<'a, 'b> {
impl<'a, 'b: 'a> IntoFuture for DynProofRequest<'a, 'b> {
type Output = Result<SP1ProofWithPublicValues>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>;

fn into_future(self) -> Self::IntoFuture {
Box::pin(async move { self.run() })
Box::pin(self.run())
}
}
101 changes: 101 additions & 0 deletions crates/sdk/src/verify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use itertools::Itertools;
use p3_field::PrimeField32;
use sp1_prover::components::DefaultProverComponents;
use std::borrow::Borrow;

use anyhow::Result;
use sp1_core_executor::SP1Context;
use sp1_core_machine::{io::SP1Stdin, SP1_CIRCUIT_VERSION};
use sp1_prover::{
components::SP1ProverComponents, CoreSC, InnerSC, SP1CoreProofData, SP1Prover, SP1ProvingKey,
SP1VerifyingKey,
};
use sp1_stark::{air::PublicValues, MachineVerificationError, Word};
use strum_macros::EnumString;
use thiserror::Error;

use crate::install::try_install_circuit_artifacts;
use crate::opts::ProofOpts;
use crate::provers::SP1VerificationError;
use crate::{proof::SP1Proof, proof::SP1ProofKind, proof::SP1ProofWithPublicValues};

/// Verify that an SP1 proof is valid given its vkey and metadata.
/// For Plonk proofs, verifies that the public inputs of the PlonkBn254 proof match
/// the hash of the VK and the committed public values of the SP1ProofWithPublicValues.
pub fn verify(
prover: &SP1Prover<DefaultProverComponents>,
version: &str,
bundle: &SP1ProofWithPublicValues,
vk: &SP1VerifyingKey,
) -> Result<(), SP1VerificationError> {
if bundle.sp1_version != version {
return Err(SP1VerificationError::VersionMismatch(bundle.sp1_version.clone()));
}
match &bundle.proof {
SP1Proof::Core(proof) => {
let public_values: &PublicValues<Word<_>, _> =
proof.last().unwrap().public_values.as_slice().borrow();

// Get the committed value digest bytes.
let committed_value_digest_bytes = public_values
.committed_value_digest
.iter()
.flat_map(|w| w.0.iter().map(|x| x.as_canonical_u32() as u8))
.collect_vec();

// Make sure the committed value digest matches the public values hash.
for (a, b) in committed_value_digest_bytes.iter().zip_eq(bundle.public_values.hash()) {
if *a != b {
return Err(SP1VerificationError::InvalidPublicValues);
}
}

// Verify the core proof.
prover.verify(&SP1CoreProofData(proof.clone()), vk).map_err(SP1VerificationError::Core)
}
SP1Proof::Compressed(proof) => {
let public_values: &PublicValues<Word<_>, _> =
proof.proof.public_values.as_slice().borrow();

// Get the committed value digest bytes.
let committed_value_digest_bytes = public_values
.committed_value_digest
.iter()
.flat_map(|w| w.0.iter().map(|x| x.as_canonical_u32() as u8))
.collect_vec();

// Make sure the committed value digest matches the public values hash.
for (a, b) in committed_value_digest_bytes.iter().zip_eq(bundle.public_values.hash()) {
if *a != b {
return Err(SP1VerificationError::InvalidPublicValues);
}
}

prover.verify_compressed(proof, vk).map_err(SP1VerificationError::Recursion)
}
SP1Proof::Plonk(proof) => prover
.verify_plonk_bn254(
proof,
vk,
&bundle.public_values,
&if sp1_prover::build::sp1_dev_mode() {
sp1_prover::build::plonk_bn254_artifacts_dev_dir()
} else {
try_install_circuit_artifacts("plonk")
},
)
.map_err(SP1VerificationError::Plonk),
SP1Proof::Groth16(proof) => prover
.verify_groth16_bn254(
proof,
vk,
&bundle.public_values,
&if sp1_prover::build::sp1_dev_mode() {
sp1_prover::build::groth16_bn254_artifacts_dev_dir()
} else {
try_install_circuit_artifacts("groth16")
},
)
.map_err(SP1VerificationError::Groth16),
}
}
5 changes: 3 additions & 2 deletions examples/fibonacci/script/bin/network.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use sp1_sdk::network_v2::{Error, FulfillmentStrategy};
use sp1_sdk::{include_elf, utils, ProverClient, SP1ProofWithPublicValues, SP1Stdin};
use sp1_sdk::{include_elf, utils, client::ProverClient, proof::SP1ProofWithPublicValues, SP1Stdin};
use std::time::Duration;

/// The ELF we want to execute inside the zkVM.
const ELF: &[u8] = include_elf!("fibonacci-program");

fn main() {
#[tokio::main]
async fn main() {
// Setup logging.
utils::setup_logger();

Expand Down

0 comments on commit 1dbb0d4

Please sign in to comment.