Skip to content

Commit

Permalink
hm
Browse files Browse the repository at this point in the history
  • Loading branch information
John Guibas authored and John Guibas committed Feb 10, 2024
2 parents 2e3a4d4 + 5c508c0 commit 4740937
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 28 deletions.
34 changes: 22 additions & 12 deletions cli/src/commands/prove.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use anyhow::Result;
use clap::Parser;
use std::{env, fs, io::Write, path::PathBuf, process::Command};
use std::{
env,
fs::{self, File},
io::Read,
path::PathBuf,
process::Command,
};
use succinct_core::{
runtime::{Program, Runtime},
utils::{self, prove_core},
utils::{self},
SuccinctProver, SuccinctStdin,
};

use crate::CommandExecutor;
Expand Down Expand Up @@ -72,18 +78,22 @@ impl ProveCmd {
utils::setup_tracer();
}

let program = Program::from_elf(elf_path.as_path().as_str());
let mut runtime = Runtime::new(program);
let mut elf = Vec::new();
File::open(elf_path.as_path().as_str())
.expect("failed to open input file")
.read_to_end(&mut elf)
.expect("failed to read from input file");

let mut stdin = SuccinctStdin::new();
for input in self.input.clone() {
runtime.write_stdin(&input);
stdin.write(&input);
}
runtime.run();
let proof = prove_core(&mut runtime);
let serialized_json = serde_json::to_string(&proof).expect("failed to serialize proof");
let proof = SuccinctProver::prove(&elf, stdin).unwrap();

if let Some(ref path) = self.output {
let mut file = fs::File::create(path).expect("Failed to create file");
file.write_all(serialized_json.as_bytes())
.expect("Failed to write to file");
proof
.save(path.to_str().unwrap())
.expect("failed to save proof");
}

Ok(())
Expand Down
8 changes: 6 additions & 2 deletions core/src/io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::utils::{BabyBearBlake3, Buffer};
use crate::stark::StarkGenericConfig;
use crate::utils::Buffer;
use crate::Proof;

/// Standard input for the prover.
Expand Down Expand Up @@ -67,7 +68,10 @@ impl SuccinctStdout {
}
}

pub fn serialize_proof<S>(proof: &Proof<BabyBearBlake3>, serializer: S) -> Result<S::Ok, S::Error>
pub fn serialize_proof<S, SC: StarkGenericConfig + Serialize>(
proof: &Proof<SC>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Expand Down
70 changes: 63 additions & 7 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ pub mod utils;
pub use io::*;

use anyhow::Result;
use p3_commit::Pcs;
use p3_matrix::dense::RowMajorMatrix;
use runtime::{Program, Runtime};
use serde::de::DeserializeOwned;
use serde::Serialize;
use stark::{ProgramVerificationError, Proof, RiscvStark};
use stark::{MainData, OpeningProof, ProgramVerificationError, Proof};
use stark::{RiscvStark, StarkGenericConfig};
use std::fs;
use utils::{prove_core, BabyBearBlake3, StarkUtils};

Expand All @@ -46,9 +50,9 @@ pub struct SuccinctVerifier;

/// A proof of a RISCV ELF execution with given inputs and outputs.
#[derive(Serialize)]
pub struct SuccinctProofWithIO {
pub struct SuccinctProofWithIO<SC: StarkGenericConfig + Serialize> {
#[serde(serialize_with = "serialize_proof")]
pub proof: Proof<BabyBearBlake3>,
pub proof: Proof<SC>,
pub stdin: SuccinctStdin,
pub stdout: SuccinctStdout,
}
Expand All @@ -64,14 +68,42 @@ impl SuccinctProver {
}

/// Generate a proof for the execution of the ELF with the given public inputs.
pub fn prove(elf: &[u8], stdin: SuccinctStdin) -> Result<SuccinctProofWithIO> {
pub fn prove(elf: &[u8], stdin: SuccinctStdin) -> Result<SuccinctProofWithIO<BabyBearBlake3>> {
let program = Program::from(elf);
let mut runtime = Runtime::new(program);
runtime.write_stdin_slice(&stdin.buffer.data);
tracing::info_span!("runtime.run(...)").in_scope(|| {
runtime.run();
});
let proof = prove_core(&mut runtime);
let config = BabyBearBlake3::new();
let proof = prove_core(config, &mut runtime);
Ok(SuccinctProofWithIO {
proof,
stdin,
stdout: SuccinctStdout::from(&runtime.state.output_stream),
})
}

/// Generate a proof for the execution of the ELF with the given public inputs and a custom config.
pub fn prove_with_config<SC: StarkGenericConfig>(
elf: &[u8],
stdin: SuccinctStdin,
config: SC,
) -> Result<SuccinctProofWithIO<SC>>
where
SC: StarkUtils + Send + Sync + Serialize + Clone,
SC::Challenger: Clone,
OpeningProof<SC>: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::Commitment: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::ProverData: Send + Sync,
MainData<SC>: Serialize + DeserializeOwned,
<SC as StarkGenericConfig>::Val: p3_field::PrimeField32,
{
let program = Program::from(elf);
let mut runtime = Runtime::new(program);
runtime.write_stdin_slice(&stdin.buffer.data);
runtime.run();
let proof = prove_core(config, &mut runtime);
Ok(SuccinctProofWithIO {
proof,
stdin,
Expand All @@ -83,15 +115,39 @@ impl SuccinctProver {
impl SuccinctVerifier {
/// Verify a proof generated by `SuccinctProver`.
#[allow(unused_variables)]
pub fn verify(elf: &[u8], proof: &SuccinctProofWithIO) -> Result<(), ProgramVerificationError> {
pub fn verify(
elf: &[u8],
proof: &SuccinctProofWithIO<BabyBearBlake3>,
) -> Result<(), ProgramVerificationError> {
let config = BabyBearBlake3::new();
let mut challenger = config.challenger();
let (machine, prover_data) = RiscvStark::init(config);
machine.verify(&mut challenger, &proof.proof)
}

/// Verify a proof generated by `SuccinctProver` with a custom config.
#[allow(unused_variables)]
pub fn verify_with_config<SC: StarkGenericConfig>(
elf: &[u8],
proof: &SuccinctProofWithIO<SC>,
config: SC,
) -> Result<(), ProgramVerificationError>
where
SC: StarkUtils + Send + Sync + Serialize,
SC::Challenger: Clone,
OpeningProof<SC>: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::Commitment: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::ProverData: Send + Sync,
MainData<SC>: Serialize + DeserializeOwned,
<SC as StarkGenericConfig>::Val: p3_field::PrimeField32,
{
let mut challenger = config.challenger();
let (machine, prover_data) = RiscvStark::init(config);
machine.verify(&mut challenger, &proof.proof)
}
}

impl SuccinctProofWithIO {
impl<SC: StarkGenericConfig + Serialize> SuccinctProofWithIO<SC> {
/// Saves the proof as a JSON to the given path.
pub fn save(&self, path: &str) -> Result<()> {
let data = serde_json::to_string(self).unwrap();
Expand Down
5 changes: 3 additions & 2 deletions core/src/runtime/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub mod tests {
use super::*;
use crate::runtime::Program;
use crate::utils::tests::IO_ELF;
use crate::utils::{self, prove_core};
use crate::utils::{self, prove_core, BabyBearBlake3};
use serde::Deserialize;

#[derive(Serialize, Deserialize, Debug, PartialEq)]
Expand Down Expand Up @@ -96,6 +96,7 @@ pub mod tests {
runtime.write_stdin(&points.0);
runtime.write_stdin(&points.1);
runtime.run();
prove_core(&mut runtime);
let config = BabyBearBlake3::new();
prove_core(config, &mut runtime);
}
}
4 changes: 3 additions & 1 deletion core/src/syscall/precompiles/k256/decompress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ pub mod tests {
use rand::SeedableRng;

use crate::utils::tests::SECP256K1_DECOMPRESS_ELF;
use crate::utils::BabyBearBlake3;
use crate::{
runtime::{Program, Runtime},
utils::{prove_core, setup_logger},
Expand All @@ -396,7 +397,8 @@ pub mod tests {
runtime.read_stdout_slice(&mut result);

assert_eq!(result, decompressed);
prove_core(&mut runtime);
let config = BabyBearBlake3::new();
prove_core(config, &mut runtime);
}
}
}
56 changes: 52 additions & 4 deletions core/src/utils/prove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ use std::time::Instant;
use crate::utils::poseidon2_instance::RC_16_30;
use crate::{
runtime::{Program, Runtime},
stark::{LocalProver, RiscvStark, StarkGenericConfig},
stark::{LocalProver, MainData, OpeningProof},
stark::{RiscvStark, StarkGenericConfig},
};
pub use baby_bear_blake3::BabyBearBlake3;
use p3_commit::Pcs;
use p3_field::PrimeField32;
use serde::de::DeserializeOwned;
use serde::Serialize;
use size::Size;

pub trait StarkUtils: StarkGenericConfig {
Expand Down Expand Up @@ -37,16 +42,27 @@ pub fn prove(program: Program) -> crate::stark::Proof<BabyBearBlake3> {
runtime.run();
runtime
});
prove_core(&mut runtime)
let config = BabyBearBlake3::new();
prove_core(config, &mut runtime)
}

pub fn prove_elf(elf: &[u8]) -> crate::stark::Proof<BabyBearBlake3> {
let program = Program::from(elf);
prove(program)
}

pub fn prove_core(runtime: &mut Runtime) -> crate::stark::Proof<BabyBearBlake3> {
let config = BabyBearBlake3::new();
pub fn prove_core<SC: StarkGenericConfig + StarkUtils + Send + Sync + Serialize + Clone>(
config: SC,
runtime: &mut Runtime,
) -> crate::stark::Proof<SC>
where
SC::Challenger: Clone,
OpeningProof<SC>: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::Commitment: Send + Sync,
<SC::Pcs as Pcs<SC::Val, RowMajorMatrix<SC::Val>>>::ProverData: Send + Sync,
MainData<SC>: Serialize + DeserializeOwned,
<SC as StarkGenericConfig>::Val: PrimeField32,
{
let mut challenger = config.challenger();

let start = Instant::now();
Expand Down Expand Up @@ -141,6 +157,7 @@ pub(super) mod baby_bear_poseidon2 {
use p3_merkle_tree::FieldMerkleTreeMmcs;
use p3_poseidon2::{DiffusionMatrixBabybear, Poseidon2};
use p3_symmetric::{PaddingFreeSponge, TruncatedPermutation};
use serde::Serialize;

use crate::stark::StarkGenericConfig;

Expand Down Expand Up @@ -171,6 +188,21 @@ pub(super) mod baby_bear_poseidon2 {
pcs: Pcs,
}

impl Serialize for BabyBearPoseidon2 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_none()
}
}

impl Clone for BabyBearPoseidon2 {
fn clone(&self) -> Self {
Self::new()
}
}

impl BabyBearPoseidon2 {
pub fn new() -> Self {
let perm = Perm::new(8, 22, RC_16_30.to_vec(), DiffusionMatrixBabybear);
Expand Down Expand Up @@ -249,6 +281,7 @@ pub(super) mod baby_bear_keccak {
use p3_merkle_tree::FieldMerkleTreeMmcs;
use p3_poseidon2::{DiffusionMatrixBabybear, Poseidon2};
use p3_symmetric::{SerializingHasher32, TruncatedPermutation};
use serde::Serialize;

use crate::stark::StarkGenericConfig;

Expand Down Expand Up @@ -279,6 +312,15 @@ pub(super) mod baby_bear_keccak {
pcs: Pcs,
}

impl Serialize for BabyBearKeccak {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_none()
}
}

impl BabyBearKeccak {
#[allow(dead_code)]
pub fn new() -> Self {
Expand Down Expand Up @@ -306,6 +348,12 @@ pub(super) mod baby_bear_keccak {
}
}

impl Clone for BabyBearKeccak {
fn clone(&self) -> Self {
Self::new()
}
}

impl StarkUtils for BabyBearKeccak {
type UniConfig = Self;

Expand Down

0 comments on commit 4740937

Please sign in to comment.