Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SP1 prover in gramine and verifier in CosmWasm #9

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c8ccdc6
Initial impl of prover enclave
hu55a1n1 Oct 23, 2024
f495a2f
Save proof to file
hu55a1n1 Oct 23, 2024
920a9bb
Init SP1 verifier in CosmWasm
hu55a1n1 Oct 23, 2024
72b9980
Serialize proof as hex and print to stdout
hu55a1n1 Oct 24, 2024
7343f58
Add verifier code
hu55a1n1 Oct 24, 2024
a214d00
Default instantiate impl
hu55a1n1 Oct 24, 2024
4c3db42
Print proof and vk in enclave
hu55a1n1 Oct 24, 2024
ca2dbdf
ExecuteMsg::VerifyProof fields b64
hu55a1n1 Oct 25, 2024
cd0e60d
Output execute msg directly from prover
hu55a1n1 Oct 25, 2024
f62555f
Major cleanup for reducing bin size
hu55a1n1 Oct 25, 2024
cd7985f
Add deploy script
hu55a1n1 Oct 25, 2024
9a160f3
Use groth16 prover
hu55a1n1 Oct 25, 2024
cf3f325
minor cleanup
hu55a1n1 Oct 25, 2024
7fa4820
Only support core verification
hu55a1n1 Oct 25, 2024
0691553
Use sp1_verifier crate from yuwen/verifier-crate
hu55a1n1 Oct 29, 2024
76c564d
Add rust-toolchain.toml
hu55a1n1 Oct 30, 2024
4402487
Impl dummy VerifyBls12PairingEquality
hu55a1n1 Oct 30, 2024
fa3bf17
update deploy script for neutrond
hu55a1n1 Oct 30, 2024
dd88de1
Impl VerifyBls12PairingEqualityRaw
hu55a1n1 Oct 30, 2024
775924a
Back to opt-level 3
hu55a1n1 Oct 30, 2024
64f8d87
Impl VerifyProofFrame (& import groth16 verifier)
hu55a1n1 Nov 1, 2024
e3bba0e
VerifyCompressedProof impl
hu55a1n1 Nov 5, 2024
9ee2c0f
Update prover to output compressed proof
hu55a1n1 Nov 5, 2024
6144c66
Noir gramine prover
hu55a1n1 Nov 7, 2024
9d633d5
Call nargo and bb from enclave
hu55a1n1 Nov 8, 2024
7686783
Update README.md
hu55a1n1 Nov 8, 2024
66bf360
Increase max_threads to 8
hu55a1n1 Nov 8, 2024
8c7eb0f
Fix gramine paths
hu55a1n1 Nov 8, 2024
bb53149
Try commands that wopnt fail
hu55a1n1 Nov 8, 2024
0e0c19d
Update README.md with output
hu55a1n1 Nov 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions zk/noir/gramine-noir-prover/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
7 changes: 7 additions & 0 deletions zk/noir/gramine-noir-prover/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "gramine-noir-prover"
version = "0.1.0"
edition = "2021"

[dependencies]
hex = "0.4.3"
29 changes: 29 additions & 0 deletions zk/noir/gramine-noir-prover/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Noir prover in gramine

```
$ sudo apt install libc++1 libc++-dev # optional dependency

$ gramine-manifest \
-Dlog_level=error \
-Dhome=$HOME \
-Darch_libdir=/lib/x86_64-linux-gnu \
-Dra_type=dcap -Dra_client_linkable=1 \
-Dbin_path=`pwd`/target/release/gramine-noir-prover \
-Dnargo_path="$HOME"/.nargo/bin/nargo \
-Dbb_path="$HOME"/.bb/bb \
gramine-noir-prover.manifest.template gramine-noir-prover.manifest

$ gramine-sgx-sign --manifest gramine-noir-prover.manifest --output gramine-noir-prover.manifest.sgx

$ gramine-sgx ./gramine-noir-prover
Gramine is starting. Parsing TOML manifest file, this may take some time...
Running 'nargo execute'...
nargo --version output:
nargo version = 0.36.0
noirc version = 0.36.0+801c71880ecf8386a26737a5d8bb5b4cb164b2ab
(git version hash: 801c71880ecf8386a26737a5d8bb5b4cb164b2ab, is dirty: false)

Running 'bb prove'...
bb --version output:
0.58.0
```
46 changes: 46 additions & 0 deletions zk/noir/gramine-noir-prover/gramine-noir-prover.manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Manifest file for creating dummy quotes

libos.entrypoint = "{{ bin_path }}"

loader.log_level = "{{ log_level }}"
loader.entrypoint = "file:{{ gramine.libos }}"
loader.env.LD_LIBRARY_PATH = "/lib:/usr/local/lib:{{ arch_libdir }}:/usr{{ arch_libdir }}"
loader.env.HOME = "{{ home }}"
loader.env.INSIDE_SGX = "1"
loader.env.TLS = { passthrough = true }
loader.env.RA_TYPE = { passthrough = true }
loader.env.RA_TLS_ALLOW_DEBUG_ENCLAVE_INSECURE = { passthrough = true }
loader.env.RA_TLS_ALLOW_OUTDATED_TCB_INSECURE = { passthrough = true }
loader.env.RA_TLS_MRENCLAVE = { passthrough = true }
loader.env.RA_TLS_MRSIGNER = { passthrough = true }
loader.env.RA_TLS_ISV_SVN = { passthrough = true }
loader.env.RA_TLS_ISV_PROD_ID = { passthrough = true }
loader.env.MYAPP_DATA = { passthrough = true }

fs.mounts = [
{ uri = "file:{{ gramine.runtimedir() }}", path = "/lib" },
{ uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" },
{ uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" },
{ uri = "file:{{ bin_path }}", path = "{{ bin_path }}" },
{ uri = "file:{{ nargo_path }}", path = "/usr/bin/nargo" },
{ uri = "file:{{ bb_path }}", path = "/usr/bin/bb" },
]

sgx.enclave_size = "512M"
sgx.max_threads = 8
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}

sgx.remote_attestation = "{{ ra_type }}"
sgx.ra_client_linkable = {{ 'true' if ra_client_linkable == '1' else 'false' }}

sgx.trusted_files = [
"file:{{ gramine.libos }}",
"file:{{ bin_path }}",
"file:{{ nargo_path }}",
"file:{{ bb_path }}",
"file:{{ gramine.runtimedir() }}/",
"file:{{ arch_libdir }}/",
"file:/usr/{{ arch_libdir }}/",
]

sys.enable_sigterm_injection = true
38 changes: 38 additions & 0 deletions zk/noir/gramine-noir-prover/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::error::Error;
use std::process::{Command, Output, Stdio};

fn run_command(cmd: &str, args: &[&str]) -> Result<Output, Box<dyn Error>> {
let output = Command::new(cmd)
.args(args)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?;

if output.status.success() {
println!(
"{} {} output:\n{}",
cmd,
args.join(" "),
String::from_utf8_lossy(&output.stdout)
);
} else {
eprintln!(
"{} {} failed:\n{}",
cmd,
args.join(" "),
String::from_utf8_lossy(&output.stderr)
);
}

Ok(output)
}

fn main() -> Result<(), Box<dyn Error>> {
println!("Running 'nargo execute'...");
run_command("nargo", &["--version"])?;

println!("Running 'bb prove'...");
run_command("bb", &["--version"])?;

Ok(())
}
5 changes: 5 additions & 0 deletions zk/sp1/sp1-cw/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[alias]
wasm = "build --release --lib --target wasm32-unknown-unknown"
unit-test = "test --lib"
schema = "run --bin schema"
integration-test = "test --lib integration_tests"
16 changes: 16 additions & 0 deletions zk/sp1/sp1-cw/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Build results
/target
/schema

# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327)
.cargo-ok

# Text file backups
**/*.rs.bk

# macOS
.DS_Store

# IDEs
*.iml
.idea
47 changes: 47 additions & 0 deletions zk/sp1/sp1-cw/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "sp1-cw"
version = "0.1.0"
authors = ["hu55a1n1 <[email protected]>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[profile.release]
opt-level = 3
debug = false
rpath = false
lto = true
debug-assertions = false
codegen-units = 1
panic = 'abort'
incremental = false
overflow-checks = true

[features]
# use library feature to disable all instantiate/execute/query exports
library = []

[package.metadata.scripts]
optimize = """docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/optimizer:0.15.0
"""

[dependencies]
cosmwasm-crypto = { version = "2.1.4", default-features = false }
cosmwasm-schema = { version = "2.1.0", default-features = false }
cosmwasm-std = { version = "2.1.0", default-features = false, features = ["std", "cosmwasm_2_1"] }
hex-literal = "0.4.1"
sp1-verifier = { path = "../../../../sp1/crates/verifier", default-features = false }
bincode = { version = "1.3.3", default-features = false }

bn = { git = "https://github.com/yuwen01/bn", branch = "yuwen/sp1-flag", package = "substrate-bn" }
sha2 = { version = "0.10.8", default-features = false }
thiserror-no-std = "2.0.2"
rand = { version = "0.8.5", default-features = false }
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
lazy_static = { version = "1.5.0", default-features = false }
1 change: 1 addition & 0 deletions zk/sp1/sp1-cw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# SP1 verifier in CosmWasm
60 changes: 60 additions & 0 deletions zk/sp1/sp1-cw/deploy-contract.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash

# Deploy the specified contract's `WASM_BIN` to the chain specified by `CHAIN_ID` using the `USER_ADDR` account.
set -eo pipefail

USER_ADDR=${USER_ADDR:-$(neutrond keys show -a admin)}
WASM_BIN="$1"
CHAIN_ID=${CHAIN_ID:-pion-1}
NODE_URL=${NODE_URL:-https://rpc-falcron.pion-1.ntrn.tech}
LABEL=${LABEL:-sp1-verifier}
COUNT=${COUNT:-0}
ROOT=${ROOT:-.}
WASM_BIN_DIR="$ROOT/target/wasm32-unknown-unknown/release"
TXFLAG="--chain-id ${CHAIN_ID} --gas-prices 0.025untrn --gas auto --gas-adjustment 1.8"
CMD="neutrond --node $NODE_URL"

# Deploy Contract
echo "$WASM_BIN_DIR/$WASM_BIN"
echo "🚀 Deploying WASM contract $WASM_BIN_DIR/$WASM_BIN on chain '${CHAIN_ID}' using account '${USER_ADDR}'..."
echo " with cmd : $CMD"
echo "===================================================================="

RES=$($CMD tx wasm store "$WASM_BIN_DIR/$WASM_BIN" --from "$USER_ADDR" $TXFLAG -y --output json)
echo $RES
TX_HASH=$(echo $RES | jq -r '.["txhash"]')

while ! $CMD query tx $TX_HASH &> /dev/null; do
echo "... 🕐 waiting for contract to deploy from tx hash $TX_HASH"
sleep 1
done

RES=$($CMD query tx "$TX_HASH" --output json)
CODE_ID=$(echo $RES | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
echo $CODE_ID

echo ""
echo "🚀 Instantiating contract with the following parameters:"
echo "--------------------------------------------------------"
echo "Label: ${LABEL}"
echo "code_id: ${CODE_ID}"
echo "--------------------------------------------------------"

RES=$($CMD --keyring-backend=test tx wasm instantiate "$CODE_ID" "{}" --from "$USER_ADDR" --label $LABEL $TXFLAG -y --no-admin --output json)
TX_HASH=$(echo $RES | jq -r '.["txhash"]')

echo ""
while ! $CMD query tx $TX_HASH &> /dev/null; do
echo "... 🕐 waiting for contract to be queryable"
sleep 1
done

RES=$($CMD query wasm list-contract-by-code "$CODE_ID" --output json)
CONTRACT=$(echo $RES | jq -r '.contracts[0]')

echo "🚀 Successfully deployed and instantiated contract!"
echo "🔗 Chain ID: ${CHAIN_ID}"
echo "🆔 Code ID: ${CODE_ID}"
echo "📌 Contract Address: ${CONTRACT}"
echo "🔑 Contract Key: ${KEY}"
echo "🔖 Contract Label: ${LABEL}"
3 changes: 3 additions & 0 deletions zk/sp1/sp1-cw/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "1.81.0"
targets = ["wasm32-unknown-unknown"]
31 changes: 31 additions & 0 deletions zk/sp1/sp1-cw/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/// Gnark (and arkworks) use the 2 most significant bits to encode the flag for a compressed point.
pub(crate) const MASK: u8 = 0b11 << 6;

/// The flags for a positive, negative, or infinity compressed point.
pub(crate) const COMPRESSED_POSITIVE: u8 = 0b10 << 6;
pub(crate) const COMPRESSED_NEGATIVE: u8 = 0b11 << 6;
pub(crate) const COMPRESSED_INFINITY: u8 = 0b01 << 6;

#[derive(Debug, PartialEq, Eq)]
pub(crate) enum CompressedPointFlag {
Positive = COMPRESSED_POSITIVE as isize,
Negative = COMPRESSED_NEGATIVE as isize,
Infinity = COMPRESSED_INFINITY as isize,
}

impl From<u8> for CompressedPointFlag {
fn from(val: u8) -> Self {
match val {
COMPRESSED_POSITIVE => CompressedPointFlag::Positive,
COMPRESSED_NEGATIVE => CompressedPointFlag::Negative,
COMPRESSED_INFINITY => CompressedPointFlag::Infinity,
_ => panic!("Invalid compressed point flag"),
}
}
}

impl From<CompressedPointFlag> for u8 {
fn from(value: CompressedPointFlag) -> Self {
value as u8
}
}
Loading