Skip to content

Commit

Permalink
1) update to latest release risc0
Browse files Browse the repository at this point in the history
2) update ring (fix build under current risc0)
3) update local prover and verifier contract
tolak committed Nov 7, 2024
1 parent e888dcc commit be5e377
Showing 25 changed files with 1,838 additions and 925 deletions.
5 changes: 0 additions & 5 deletions .cargo/config.toml

This file was deleted.

12 changes: 6 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/murky"]
path = lib/murky
url = https://github.com/dmfxyz/murky
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/solidity-bytes-utils"]
path = lib/solidity-bytes-utils
url = https://github.com/GNSPS/solidity-bytes-utils
[submodule "lib/risc0-ethereum"]
path = lib/risc0-ethereum
url = https://github.com/risc0/risc0-ethereum
[submodule "lib/murky"]
path = lib/murky
url = https://github.com/dmfxyz/murky
[submodule "lib/solidity-bytes-utils"]
path = lib/solidity-bytes-utils
url = https://github.com/GNSPS/solidity-bytes-utils
2,306 changes: 1,636 additions & 670 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 15 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
[workspace]
resolver = "2"
members = ["apps", "methods", "primitive-io"]
members = ["apps", "methods", "primitive-io", "methods/guest"]
exclude = ["lib"]

[workspace.package]
version = "0.1.0"
edition = "2021"

[workspace.dependencies]
alloy-primitives = { version = "0.6", default-features = false, features = ["rlp", "serde", "std"] }
alloy-sol-types = { version = "0.6" }
alloy = { version = "0.3", features = ["full"] }
alloy-primitives = { version = "0.7", default-features = false, features = ["rlp", "serde", "std"] }
alloy-sol-types = { version = "0.7" }
anyhow = { version = "1.0.75" }
bincode = { version = "1.3" }
bonsai-sdk = { version = "0.6.1" }
@@ -18,16 +19,19 @@ ethers = { version = "2.0" }
hex = { version = "0.4" }
log = { version = "0.4" }
methods = { path = "./methods" }
# NOTE: Using a git rev temporarily to get an unreleased version of risc0-build.
# Once the referenced commit is in a released version of risc0-build, this will go back to using a version.
risc0-build = { git = "https://github.com/risc0/risc0", rev = "7f731662", features = ["docker"] }
risc0-build-ethereum = { git = "https://github.com/risc0/risc0-ethereum", branch = "release-0.7" }
risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum", branch = "release-0.7" }
risc0-zkvm = { version = "0.21.0", default-features = false }
risc0-zkp = { version = "0.21.0", default-features = false }
risc0-groth16 = { version = "0.21.0", default-features = false, features = ["prove"] }
risc0-build = { version = "1.1", features = ["docker"] }
risc0-build-ethereum = { git = "https://github.com/risc0/risc0-ethereum", tag = "v1.1.4" }
risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum", tag = "v1.1.4" }
risc0-zkvm = { version = "1.1", default-features = false, features = ["client"] }
risc0-zkp = { version = "1.1", default-features = false }
risc0-groth16 = { version = "1.1", default-features = false }
risc0-circuit-recursion = { version = "1.1", default-features = false }
risc0-zkvm-platform = { version = "1.1" }
serde = { version = "1.0", features = ["derive", "std"] }

[profile.release]
debug = 1
lto = true

[patch.crates-io]
ring = { git = "https://github.com/tolak/ring.git", branch = "patch-for-risc0" }
8 changes: 5 additions & 3 deletions apps/Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,13 +12,15 @@ bonsai-sdk = { workspace = true }
bytemuck = { workspace = true }
clap = { version = "4.0", features = ["derive", "env"] }
env_logger = { version = "0.10" }
ethers = { workspace = true }
ethers = "^2.0.14"
hex = { workspace = true }
log = { workspace = true }
methods = { workspace = true }
risc0-ethereum-contracts = { workspace = true }
risc0-zkvm = { workspace = true, features = ["prove"] }
risc0-groth16 = { workspace = true, features = ["prove"] }
risc0-zkvm = { workspace = true }
risc0-groth16 = { workspace = true }
risc0-circuit-recursion = { workspace = true }
risc0-zkvm-platform = { workspace = true }
serde = { workspace = true }
serde_bytes = "0.11"
tokio = { version = "1.35", features = ["full"] }
9 changes: 4 additions & 5 deletions apps/src/bin/publisher.rs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ impl TxSender {
// `IEvenNumber` interface automatically generated via the alloy `sol!` macro.
sol! {
interface IDCAP {
function verifyAttestation(bytes calldata output, bytes32 post_state_digest, bytes calldata seal);
function verifyAttestation(bytes calldata output, bytes calldata seal);
}
}

@@ -118,14 +118,13 @@ fn main() -> Result<()> {
log::info!("Start to generate proof for intputs");

// Send an off-chain proof request to the Bonsai proving service.
let (journal, post_state_digest, seal) =
let (journal, seal) =
LocalProver::prove(DCAP_VERIFIER_ELF, &bincode::serialize(&input).unwrap())?;

// Encode the function call for `IDCAP.verifyAttestation(x)`.
let calldata = IDCAP::IDCAPCalls::verifyAttestation(IDCAP::verifyAttestationCall {
output: journal,
post_state_digest,
seal,
output: journal.into(),
seal: seal.into(),
})
.abi_encode();

118 changes: 0 additions & 118 deletions apps/src/bonsai_prover.rs

This file was deleted.

1 change: 0 additions & 1 deletion apps/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod bonsai_prover;
pub mod local_prover;
57 changes: 18 additions & 39 deletions apps/src/local_prover.rs
Original file line number Diff line number Diff line change
@@ -15,56 +15,35 @@
// The following library provides utility functions to help generate SNARK proof
// of the execution of guest code, here by mean verify DCAP of Phala workers.

use alloy_primitives::FixedBytes;
use anyhow::Result;
use risc0_groth16::docker::stark_to_snark;
use risc0_zkvm::{
get_prover_server, recursion::identity_p254, sha::Digestible, ExecutorEnv, ExecutorImpl,
ProverOpts, VerifierContext,
};
use risc0_ethereum_contracts::encode_seal;
use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, VerifierContext};

/// An implementation of a Prover that runs on local machine.
pub struct LocalProver {}
impl LocalProver {
/// Generates a snark proof as a triplet (`Vec<u8>`, `FixedBytes<32>`,
/// `Vec<u8>) for the given elf and input.
pub fn prove(elf: &[u8], input: &[u8]) -> Result<(Vec<u8>, FixedBytes<32>, Vec<u8>)> {
log::info!("Start local proving");
let env = ExecutorEnv::builder()
.write_slice(input)
// .unwrap()
.build()
.unwrap();

log::info!("Create execution session");
let mut exec = ExecutorImpl::from_elf(env, elf).unwrap();
let session = exec.run().unwrap();

log::info!("Generate STARK proof");
let opts = ProverOpts::default();
let ctx = VerifierContext::default();
let prover = get_prover_server(&opts).unwrap();
let receipt = prover.prove_session(&ctx, &session).unwrap();

let claim = receipt.get_claim().unwrap();
let composite_receipt = receipt.inner.composite().unwrap();
let succinct_receipt = prover.compress(composite_receipt).unwrap();
let journal: Vec<u8> = session.journal.unwrap().bytes;
pub fn prove(elf: &[u8], input: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> {
let env = ExecutorEnv::builder().write_slice(input).build().unwrap();

let ident_receipt = identity_p254(&succinct_receipt).unwrap();
let seal_bytes = ident_receipt.get_seal_bytes();

log::info!("Start translate STARK to SNARK");
let seal = stark_to_snark(&seal_bytes).unwrap().to_vec();
log::info!("Start local proving");
let prover_info = default_prover().prove_with_ctx(
env,
&VerifierContext::default(),
elf,
&ProverOpts::groth16(),
)?;
log::info!(
"Transform finish, proof size decrease from {:} bytes to {:} bytes, snark proof {:?}",
seal_bytes.len(),
seal.len(),
hex::encode(&seal)
"Proving finished, receipt: {:?}, stats: {:?}",
&prover_info.receipt,
&prover_info.stats
);
let post_state_digest: [u8; 32] = claim.post.digest().into();

Ok((journal, post_state_digest.into(), seal))
let seal = encode_seal(&prover_info.receipt)?;
let journal = prover_info.receipt.journal.bytes.clone();

Ok((journal, seal))
}
}

4 changes: 2 additions & 2 deletions contracts/DcapVerifier.sol
Original file line number Diff line number Diff line change
@@ -38,12 +38,12 @@ contract DcapVerifier is Ownable {
}

/// @notice Check the proof of attestation verification and return the attestation output.
function verifyAttestation(bytes calldata x, bytes32 postStateDigest, bytes calldata seal)
function verifyAttestation(bytes calldata x, bytes calldata seal)
external
returns(bytes memory) {
// Construct the expected journal data. Verify will fail if journal does not match.
bytes memory journal = x;
require(verifier.verify(seal, imageId, postStateDigest, sha256(journal)));
verifier.verify(seal, imageId, sha256(journal));

return journal;
}
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -4,5 +4,6 @@ out = "out"
libs = ["lib"]
test = "tests"
ffi = true
fs_permissions = [{ access = "read-write", path = "./"}]

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
2 changes: 1 addition & 1 deletion lib/openzeppelin-contracts
2 changes: 1 addition & 1 deletion lib/risc0-ethereum
Submodule risc0-ethereum updated 232 files
1 change: 1 addition & 0 deletions methods/build.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ fn main() {

// Builds can be made deterministic, and thereby reproducible, by using Docker to build the
// guest. Check the RISC0_USE_DOCKER variable and use Docker to build the guest if set.
println!("cargo:rerun-if-env-changed=RISC0_USE_DOCKER");
let use_docker = env::var("RISC0_USE_DOCKER").ok().map(|_| DockerOptions {
root_dir: Some("../".into()),
});
18 changes: 6 additions & 12 deletions methods/guest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
[package]
name = "guests"
version = "0.1.0"
edition = "2021"
version = { workspace = true }
edition = { workspace = true }

[[bin]]
name = "dcap-verifier"
path = "src/main.rs"

[workspace]

[dependencies]
alloy-primitives = { version = "0.6", default-features = false, features = ["rlp", "serde", "std"] }
alloy-sol-types = { version = "0.6" }
risc0-zkvm = { version = "0.20.1", default-features = false, features = ['std'] }
alloy-primitives = { workspace = true }
alloy-sol-types = { workspace = true }
risc0-zkvm = { workspace = true, features = ["client"] }

primitive-io = { path = "../../primitive-io" }

@@ -36,7 +34,7 @@ asn1_der = { version = "0.7", default-features = false, features = [
"native_types",
"std",
] }
ring = { version = "0.17.5", default-features = false, features = ["std"] }
ring = { version = "0.17.8", default-features = false, features = ["std"] }
const-oid = { version = "0.9.5", default-features = false, features = ["std"] }
der = { version = "0.7.8", default-features = false, features = ["std"] }
pem = { version = "3", default-features = false, features = ["std"] }
@@ -46,7 +44,3 @@ webpki = { package = "rustls-webpki", version = "=0.102.6", default-features = f

[profile.release]
lto = "thin"


[patch.crates-io]
ring = { git = "https://github.com/tolak/ring.git", package = "ring", branch = "patch-for-risc0" }
30 changes: 18 additions & 12 deletions methods/guest/src/dcap.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod constants;
mod quote;
mod tcb_info;
mod constants;
mod utils;

use alloc::borrow::ToOwned;
@@ -9,9 +9,9 @@ use alloc::vec::Vec;
use scale_codec::{Decode, Encode};
use scale_info::TypeInfo;

use crate::dcap::constants::*;
use crate::dcap::quote::{AuthData, EnclaveReport, Quote};
use crate::dcap::tcb_info::TcbInfo;
use crate::dcap::constants::*;
use crate::dcap::utils::*;
use crate::Error;

@@ -42,8 +42,8 @@ pub fn verify(
let tcb_info = pink_json::from_str::<TcbInfo>(&quote_collateral.tcb_info)
.map_err(|_| Error::CodecError)?;

let next_update =
chrono::DateTime::parse_from_rfc3339(&tcb_info.next_update).map_err(|_| Error::CodecError)?;
let next_update = chrono::DateTime::parse_from_rfc3339(&tcb_info.next_update)
.map_err(|_| Error::CodecError)?;
if now > next_update.timestamp() as u64 {
return Err(Error::TCBInfoExpired);
}
@@ -104,25 +104,27 @@ pub fn verify(
return Err(Error::CertificateChainIsTooShort);
}
// Check certification_data
let leaf_cert: webpki::EndEntityCert =
webpki::EndEntityCert::try_from(&certification_certs[0])
.map_err(|_| Error::LeafCertificateParsingError)?;
let leaf_cert: webpki::EndEntityCert = webpki::EndEntityCert::try_from(&certification_certs[0])
.map_err(|_| Error::LeafCertificateParsingError)?;
let intermediate_certs = &certification_certs[1..];
verify_certificate_chain(&leaf_cert, intermediate_certs, now_in_milli)?;

// Check QE signature
let asn1_signature = encode_as_der(&auth_data.qe_report_signature)?;
if leaf_cert
.verify_signature(webpki::ring::ECDSA_P256_SHA256, &auth_data.qe_report, &asn1_signature)
.verify_signature(
webpki::ring::ECDSA_P256_SHA256,
&auth_data.qe_report,
&asn1_signature,
)
.is_err()
{
return Err(Error::RsaSignatureIsInvalid);
}

// Extract QE report from quote
let mut qe_report = auth_data.qe_report.as_slice();
let qe_report =
EnclaveReport::decode(&mut qe_report).map_err(|_err| Error::CodecError)?;
let qe_report = EnclaveReport::decode(&mut qe_report).map_err(|_err| Error::CodecError)?;

// Check QE hash
let mut qe_hash_data = [0u8; QE_HASH_DATA_BYTE_LEN];
@@ -162,8 +164,12 @@ pub fn verify(
let mut advisory_ids = Vec::<String>::new();
for tcb_level in &tcb_info.tcb_levels {
if pce_svn >= tcb_level.tcb.pce_svn {
if cpu_svn.iter().zip(&tcb_level.tcb.components).any(|(a, b)| a < &b.svn) {
continue
if cpu_svn
.iter()
.zip(&tcb_level.tcb.components)
.any(|(a, b)| a < &b.svn)
{
continue;
}

tcb_status = tcb_level.tcb_status.clone();
6 changes: 6 additions & 0 deletions methods/guest/src/dcap/quote.rs
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ impl<T: Decode + Into<u64>> Decode for Data<T> {
}

#[derive(Decode, Debug)]
#[allow(dead_code)]
pub struct Header {
pub version: u16,
pub attestation_key_type: u16,
@@ -36,12 +37,14 @@ pub struct Header {
}

#[derive(Decode, Debug)]
#[allow(dead_code)]
pub struct Body {
pub body_type: u16,
pub size: u32,
}

#[derive(Decode, Debug)]
#[allow(dead_code)]
pub struct EnclaveReport {
pub cpu_svn: [u8; 16],
pub misc_select: u32,
@@ -74,6 +77,7 @@ impl core::fmt::Debug for CertificationData {
}

#[derive(Decode, Debug)]
#[allow(dead_code)]
pub struct QEReportCertificationData {
pub qe_report: [u8; ENCLAVE_REPORT_BYTE_LEN],
pub qe_report_signature: [u8; QE_REPORT_SIG_BYTE_LEN],
@@ -92,6 +96,7 @@ pub struct AuthDataV3 {
}

#[derive(Debug)]
#[allow(dead_code)]
pub struct AuthDataV4 {
pub ecdsa_signature: [u8; ECDSA_SIGNATURE_BYTE_LEN],
pub ecdsa_attestation_key: [u8; ECDSA_PUBKEY_BYTE_LEN],
@@ -116,6 +121,7 @@ impl Decode for AuthDataV4 {
}

#[derive(Debug)]
#[allow(dead_code)]
pub enum AuthData {
V3(AuthDataV3),
V4(AuthDataV4),
44 changes: 26 additions & 18 deletions methods/guest/src/dcap/utils.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use alloc::vec;
use alloc::vec::Vec;
use core::time::Duration;
use webpki::types::CertificateDer;
use x509_cert::Certificate;
use asn1_der::{
typed::{DerDecodable, Sequence},
DerObject,
};
use core::time::Duration;
use webpki::types::CertificateDer;
use x509_cert::Certificate;

use crate::dcap::constants::*;
use crate::Error;
@@ -23,7 +23,9 @@ pub fn get_intel_extension(der_encoded: &[u8]) -> Result<Vec<u8>, Error> {
.filter(|e| e.extn_id == oids::SGX_EXTENSION)
.map(|e| e.extn_value.clone());

let extension = extension_iter.next().ok_or(Error::IntelExtensionAmbiguity)?;
let extension = extension_iter
.next()
.ok_or(Error::IntelExtensionAmbiguity)?;
if extension_iter.next().is_some() {
//"There should only be one section containing Intel extensions"
return Err(Error::IntelExtensionAmbiguity);
@@ -39,7 +41,7 @@ pub fn find_extension(path: &[&[u8]], raw: &[u8]) -> Result<Vec<u8>, Error> {

fn get_obj<'a>(path: &[&[u8]], mut obj: DerObject<'a>) -> Result<DerObject<'a>, Error> {
for oid in path {
let seq = Sequence::load(obj).map_err(|_| Error::DerDecodingError )?;
let seq = Sequence::load(obj).map_err(|_| Error::DerDecodingError)?;
obj = sub_obj(oid, seq)?;
}
Ok(obj)
@@ -48,7 +50,7 @@ fn get_obj<'a>(path: &[&[u8]], mut obj: DerObject<'a>) -> Result<DerObject<'a>,
fn sub_obj<'a>(oid: &[u8], seq: Sequence<'a>) -> Result<DerObject<'a>, Error> {
for i in 0..seq.len() {
let entry = seq.get(i).map_err(|_| Error::OidIsMissing)?;
let entry = Sequence::load(entry).map_err(|_| Error::DerDecodingError )?;
let entry = Sequence::load(entry).map_err(|_| Error::DerDecodingError)?;
let name = entry.get(0).map_err(|_| Error::OidIsMissing)?;
let value = entry.get(1).map_err(|_| Error::OidIsMissing)?;
if name.value() == oid {
@@ -61,39 +63,45 @@ fn sub_obj<'a>(oid: &[u8], seq: Sequence<'a>) -> Result<DerObject<'a>, Error> {
pub fn get_fmspc(extension_section: &[u8]) -> Result<Fmspc, Error> {
let data = find_extension(&[oids::FMSPC.as_bytes()], extension_section)?;
if data.len() != 6 {
return Err(Error::FmspcLengthMismatch)
return Err(Error::FmspcLengthMismatch);
}

data.try_into().map_err(|_| Error::FmspcDecodingError)
}

pub fn get_cpu_svn(extension_section: &[u8]) -> Result<CpuSvn, Error> {
let data = find_extension(&[oids::TCB.as_bytes(), oids::CPUSVN.as_bytes()], extension_section)?;
let data = find_extension(
&[oids::TCB.as_bytes(), oids::CPUSVN.as_bytes()],
extension_section,
)?;
if data.len() != 16 {
return Err(Error::CpuSvnLengthMismatch)
return Err(Error::CpuSvnLengthMismatch);
}

data.try_into().map_err(|_| Error::CpuSvnDecodingError)
}

pub fn get_pce_svn(extension_section: &[u8]) -> Result<Svn, Error> {
let data = find_extension(&[oids::TCB.as_bytes(), oids::PCESVN.as_bytes()], extension_section)?;
let data = find_extension(
&[oids::TCB.as_bytes(), oids::PCESVN.as_bytes()],
extension_section,
)?;

match data.len() {
1 => Ok(u16::from(data[0])),
2 => Ok(u16::from_be_bytes(data.try_into().map_err(|_| Error::PceSvnDecodingError)?)),
2 => Ok(u16::from_be_bytes(
data.try_into().map_err(|_| Error::PceSvnDecodingError)?,
)),
_ => Err(Error::PceSvnLengthMismatch),
}
}

pub fn extract_raw_certs(cert_chain: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
Ok(
pem::parse_many(cert_chain)
.map_err(|_| Error::CodecError)?
.iter()
.map(|i| i.contents().to_vec() )
.collect()
)
Ok(pem::parse_many(cert_chain)
.map_err(|_| Error::CodecError)?
.iter()
.map(|i| i.contents().to_vec())
.collect())
}

pub fn extract_certs<'a>(cert_chain: &'a [u8]) -> Result<Vec<CertificateDer<'a>>, Error> {
6 changes: 3 additions & 3 deletions methods/guest/src/main.rs
Original file line number Diff line number Diff line change
@@ -14,10 +14,10 @@
extern crate alloc;
extern crate core;

use std::io::Read;
use risc0_zkvm::guest::env;
use primitive_io::{Inputs, Outputs};
use risc0_zkvm::guest::env;
use scale_codec::Decode;
use std::io::Read;

mod error;
use error::Error;
@@ -48,7 +48,7 @@ fn main() {
isv_prod_id,
isv_svn,
tcb_status,
advisory_ids
advisory_ids,
};

log::info!("Check passed, commit output to host");
3 changes: 1 addition & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
murky_differential_testing/=lib/murky/differential_testing/
forge-std/=lib/forge-std/src/
openzeppelin/=lib/openzeppelin-contracts/
risc0/=lib/risc0-ethereum/contracts/src/
risc0/=lib/risc0-ethereum/contracts/src/
5 changes: 3 additions & 2 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[toolchain]
channel = "stable"
components = ["rustfmt", "rust-src"]
channel = "1.79"
components = ["clippy", "rustfmt", "rust-src"]
targets = []
profile = "minimal"
77 changes: 67 additions & 10 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -17,30 +17,87 @@
pragma solidity ^0.8.20;

import {Script} from "forge-std/Script.sol";
import {console2} from "forge-std/console2.sol";
import "forge-std/Test.sol";
import {RiscZeroCheats} from "risc0/test/RiscZeroCheats.sol";
import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol";
import {ControlID, RiscZeroGroth16Verifier} from "risc0/groth16/RiscZeroGroth16Verifier.sol";
import {RiscZeroGroth16Verifier} from "risc0/groth16/RiscZeroGroth16Verifier.sol";
import {ControlID} from "risc0/groth16/ControlID.sol";

import {DcapVerifier} from "../contracts/DcapVerifier.sol";

/// @notice Deployment script for the RISC Zero starter project.
/// @dev Use the following environment variable to control the deployment:
/// * ETH_WALLET_PRIVATE_KEY private key of the wallet to be used for deployment.
/// * Set one of these two environment variables to control the deployment wallet:
/// * ETH_WALLET_PRIVATE_KEY private key of the wallet account.
/// * ETH_WALLET_ADDRESS address of the wallet account.
///
/// See the Foundry documentation for more information about Solidity scripts,
/// including information about wallet options.
///
/// See the Foundry documentation for more information about Solidity scripts.
/// https://book.getfoundry.sh/tutorials/solidity-scripting
contract DcapDeploy is Script {
/// https://book.getfoundry.sh/reference/forge/forge-script
contract EvenNumberDeploy is Script, RiscZeroCheats {
// Path to deployment config file, relative to the project root.
string constant CONFIG_FILE = "script/config.toml";

IRiscZeroVerifier verifier;

function run() external {
uint256 deployerKey = uint256(vm.envBytes32("ETH_WALLET_PRIVATE_KEY"));
// Read and log the chainID
uint256 chainId = block.chainid;
console2.log("You are deploying on ChainID %d", chainId);

// Read the config profile from the environment variable, or use the default for the chainId.
// Default is the first profile with a matching chainId field.
string memory config = vm.readFile(string.concat(vm.projectRoot(), "/", CONFIG_FILE));
string memory configProfile = vm.envOr("CONFIG_PROFILE", string(""));
if (bytes(configProfile).length == 0) {
string[] memory profileKeys = vm.parseTomlKeys(config, ".profile");
for (uint256 i = 0; i < profileKeys.length; i++) {
if (stdToml.readUint(config, string.concat(".profile.", profileKeys[i], ".chainId")) == chainId) {
configProfile = profileKeys[i];
break;
}
}
}

if (bytes(configProfile).length != 0) {
console2.log("Deploying using config profile:", configProfile);
string memory configProfileKey = string.concat(".profile.", configProfile);
address riscZeroVerifierAddress =
stdToml.readAddress(config, string.concat(configProfileKey, ".riscZeroVerifierAddress"));
// If set, use the predeployed verifier address found in the config.
verifier = IRiscZeroVerifier(riscZeroVerifierAddress);
}

// Determine the wallet to send transactions from.
uint256 deployerKey = uint256(vm.envOr("ETH_WALLET_PRIVATE_KEY", bytes32(0)));
address deployerAddr = address(0);
if (deployerKey != 0) {
// Check for conflicts in how the two environment variables are set.
address envAddr = vm.envOr("ETH_WALLET_ADDRESS", address(0));
require(
envAddr == address(0) || envAddr == vm.addr(deployerKey),
"conflicting settings from ETH_WALLET_PRIVATE_KEY and ETH_WALLET_ADDRESS"
);

vm.startBroadcast(deployerKey);
vm.startBroadcast(deployerKey);
} else {
deployerAddr = vm.envAddress("ETH_WALLET_ADDRESS");
vm.startBroadcast(deployerAddr);
}

IRiscZeroVerifier verifier = new RiscZeroGroth16Verifier(ControlID.CONTROL_ID_0, ControlID.CONTROL_ID_1);
console2.log("Deployed RiscZeroGroth16Verifier to", address(verifier));
// Deploy the verifier, if not already deployed.
if (address(verifier) == address(0)) {
verifier = deployRiscZeroVerifier();
} else {
console2.log("Using IRiscZeroVerifier contract deployed at", address(verifier));
}

// Deploy the application contract.
DcapVerifier dcapVerifier = new DcapVerifier(verifier);
console2.log("Deployed DcapVerifier to", address(dcapVerifier));

vm.stopBroadcast();
}
}
}
14 changes: 14 additions & 0 deletions script/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[profile.mainnet]
# RISC Zero Verifier contract deployed on mainnet (see https://dev.risczero.com/api/blockchain-integration/contracts/verifier#deployed-verifiers)
chainId = 1
riscZeroVerifierAddress = "0x8EaB2D97Dfce405A1692a21b3ff3A172d593D319"

[profile.sepolia]
# RISC Zero Verifier contract deployed on sepolia (see https://dev.risczero.com/api/blockchain-integration/contracts/verifier#deployed-verifiers)
chainId = 11155111
riscZeroVerifierAddress = "0x925d8331ddc0a1F0d96E68CF073DFE1d92b69187"

# You can add additional profiles here
# [profile.custom]
# chainId = 11155111
# riscZeroVerifierAddress =
6 changes: 3 additions & 3 deletions tests/DcapVerifier.t.sol
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@

pragma solidity ^0.8.20;

import {RiscZeroCheats} from "risc0/RiscZeroCheats.sol";
import {RiscZeroCheats} from "risc0/test/RiscZeroCheats.sol";
import {console2} from "forge-std/console2.sol";
import {Test} from "forge-std/Test.sol";
import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol";
@@ -33,10 +33,10 @@ contract DcapVerifierTest is RiscZeroCheats, Test {

function test_VerifyAttestation() public {
bytes memory input = "hello";
(bytes memory journal, bytes32 post_state_digest, bytes memory seal) =
(bytes memory journal, bytes memory seal) =
prove(Elf.DCAP_VERIFIER_PATH, input);

bytes memory output = dcapVerifier.verifyAttestation(journal, post_state_digest, seal);
bytes memory output = dcapVerifier.verifyAttestation(journal, seal);
assertEq(output, journal);
}
}

0 comments on commit be5e377

Please sign in to comment.