Repository: nexus-xyz/nexus-zkvm
File: sdk/src/stwo/seq.rs (Rust)

Code before:
        private_input: &S,
        public_input: &T,
    ) -> Result<(Self::View, Self::Proof), <Self as Prover>::Error> {
        let private_encoded = Self::encode_input(private_input)?;
        let public_encoded = Self::encode_input(public_input)?;

        let (view, trace) = nexus_core::nvm::k_trace(
            self.elf.clone(),
            self.ad.as_slice(),
            public_encoded.as_slice(),
            private_encoded.as_slice(),
            1,
        )?;
        let proof = nexus_core::stwo::prove(&trace, &view)?;

        Ok((
            view,
            Proof {
                proof,
                memory_layout: trace.memory_layout,
            },
        ))
    }
}

impl<C: Compute> Stwo<C> {
    /// Helper function to encode input data with COBS encoding and padding.
    fn encode_input<T: Serialize>(input: &T) -> Result<Vec<u8>, IOError> {
        let mut encoded = postcard::to_stdvec(input).map_err(IOError::from)?;
        if !encoded.is_empty() {
            encoded = postcard::to_stdvec_cobs(input).map_err(IOError::from)?;
            let padded_len = (encoded.len() + 3) & !3;

            assert!(padded_len >= encoded.len());
            encoded.resize(padded_len, 0x00); // cobs ignores 0x00 padding
        }
        Ok(encoded)
    }
}

impl Verifiable for Proof {
    type View = nexus_core::nvm::View;
    type Error = Error;

    fn get_memory_layout(&self) -> &nexus_core::nvm::internals::LinearMemoryLayout {
        &self.memory_layout
    }

    fn verify(&self, view: &Self::View) -> Result<(), <Self as Verifiable>::Error> {
        nexus_core::stwo::verify(self.proof.clone(), view)?;
        Ok(())

Review comment (suggestion):
This should actually be generic over all provers, so can be moved to the `Prover` trait itself under https://github.com/nexus-xyz/nexus-zkvm/blob/main/sdk/src/traits.rs#L229

Code after:
    fn prove_with_input<S: Serialize + Sized, T: Serialize + DeserializeOwned + Sized>(
        self,
        private_input: &S,
        public_input: &T,
    ) -> Result<(Self::View, Self::Proof), <Self as Prover>::Error> {
        let private_encoded =
            <Self as Prover>::encode_input(private_input).map_err(Error::GuestIOError)?;
        let public_encoded =
            <Self as Prover>::encode_input(public_input).map_err(Error::GuestIOError)?;

        let (view, trace) = nexus_core::nvm::k_trace(
            self.elf.clone(),
            self.ad.as_slice(),
            public_encoded.as_slice(),
            private_encoded.as_slice(),
            1,
        )?;
        let proof = nexus_core::stwo::prove(&trace, &view)?;

        Ok((
            view,
            Proof {
                proof,
                memory_layout: trace.memory_layout,
            },
        ))
    }
}

impl Verifiable for Proof {
    type View = nexus_core::nvm::View;
    type Error = Error;

    fn get_memory_layout(&self) -> &nexus_core::nvm::internals::LinearMemoryLayout {
        &self.memory_layout
    }

    fn verify(&self, view: &Self::View) -> Result<(), <Self as Verifiable>::Error> {
        nexus_core::stwo::verify(self.proof.clone(), view)?;
        Ok(())
    }

    fn size_estimate(&self) -> usize {
        self.proof.size_estimate()
    }
}