1use crate::compile::Compile;
2use crate::traits::*;
3
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use std::marker::PhantomData;
6use thiserror::Error;
7
8use crate::error::{BuildError, ConfigurationError, IOError, PathError};
9
10#[derive(Debug, Error)]
12pub enum Error {
13 #[error(transparent)]
15 ProvingError(#[from] nexus_core::stwo::ProvingError),
16
17 #[error(transparent)]
19 VerificationError(#[from] nexus_core::stwo::VerificationError),
20
21 #[error(transparent)]
23 BuildError(#[from] BuildError),
24
25 #[error(transparent)]
27 HostIOError(#[from] std::io::Error),
28
29 #[error(transparent)]
31 PathError(#[from] PathError),
32
33 #[error(transparent)]
35 GuestIOError(#[from] IOError),
36
37 #[error(transparent)]
39 VMError(#[from] nexus_core::nvm::VMError),
40
41 #[error(transparent)]
43 ElfError(#[from] nexus_core::nvm::ElfError),
44
45 #[error(transparent)]
47 ConfigurationError(#[from] ConfigurationError),
48}
49
50pub struct Stwo<C: Compute = Local> {
52 pub elf: nexus_core::nvm::ElfFile,
54 pub ad: Vec<u8>,
56 _compute: PhantomData<C>,
57}
58
59#[derive(Serialize, Deserialize)]
61pub struct Proof {
62 proof: nexus_core::stwo::Proof,
63 memory_layout: nexus_core::nvm::internals::LinearMemoryLayout,
64}
65
66impl<C: Compute> ByGuestCompilation for Stwo<C>
67where
68 Stwo<C>: Prover,
69 <Stwo<C> as Prover>::Error: From<BuildError>,
70{
71 fn compile(compiler: &mut impl Compile) -> Result<Self, <Self as Prover>::Error> {
73 let elf_path = compiler.build()?;
74
75 Self::new_from_file(&elf_path)
76 }
77}
78
79impl Prover for Stwo<Local> {
80 type Proof = Proof;
81 type View = nexus_core::nvm::View;
82 type Error = Error;
83
84 fn new(elf: &nexus_core::nvm::ElfFile) -> Result<Self, <Self as Prover>::Error> {
86 Ok(Self {
87 elf: elf.clone(),
88 ad: Vec::new(),
89 _compute: PhantomData,
90 })
91 }
92
93 fn set_associated_data(&mut self, ad: &[u8]) -> Result<(), <Self as Prover>::Error> {
95 self.ad = ad.to_vec();
96 Ok(())
97 }
98
99 fn run_with_input<S: Serialize + Sized, T: Serialize + DeserializeOwned + Sized>(
101 &self,
102 private_input: &S,
103 public_input: &T,
104 ) -> Result<Self::View, <Self as Prover>::Error> {
105 let private_encoded =
106 <Self as Prover>::encode_input(private_input).map_err(Error::GuestIOError)?;
107 let public_encoded =
108 <Self as Prover>::encode_input(public_input).map_err(Error::GuestIOError)?;
109
110 let (view, _) = nexus_core::nvm::k_trace(
111 self.elf.clone(),
112 self.ad.as_slice(),
113 public_encoded.as_slice(),
114 private_encoded.as_slice(),
115 1,
116 )?; Ok(view)
119 }
120
121 fn prove_with_input<S: Serialize + Sized, T: Serialize + DeserializeOwned + Sized>(
123 self,
124 private_input: &S,
125 public_input: &T,
126 ) -> Result<(Self::View, Self::Proof), <Self as Prover>::Error> {
127 let private_encoded =
128 <Self as Prover>::encode_input(private_input).map_err(Error::GuestIOError)?;
129 let public_encoded =
130 <Self as Prover>::encode_input(public_input).map_err(Error::GuestIOError)?;
131
132 let (view, trace) = nexus_core::nvm::k_trace(
133 self.elf.clone(),
134 self.ad.as_slice(),
135 public_encoded.as_slice(),
136 private_encoded.as_slice(),
137 1,
138 )?;
139 let proof = nexus_core::stwo::prove(&trace, &view)?;
140
141 Ok((
142 view,
143 Proof {
144 proof,
145 memory_layout: trace.memory_layout,
146 },
147 ))
148 }
149}
150
151impl Verifiable for Proof {
152 type View = nexus_core::nvm::View;
153 type Error = Error;
154
155 fn get_memory_layout(&self) -> &nexus_core::nvm::internals::LinearMemoryLayout {
156 &self.memory_layout
157 }
158
159 fn verify(&self, view: &Self::View) -> Result<(), <Self as Verifiable>::Error> {
160 nexus_core::stwo::verify(self.proof.clone(), view)?;
161 Ok(())
162 }
163
164 fn size_estimate(&self) -> usize {
165 self.proof.size_estimate()
166 }
167}