Skip to content

Commit

Permalink
Add example tests & GPU support (risc0#386)
Browse files Browse the repository at this point in the history
* Add GPU features to json, pw-check, wordle

* Remove redundant json feature

* Test chess example

* Test digital-signature example

* Test JSON example

* Format

* Test password-checker

* Add tests to wordle example

* Clean pw checker test dependencies

* Format

* Update GPU features

* Turn on GPU features in CI for examples

* Add default feature to examples crates
  • Loading branch information
tzerrell authored Feb 16, 2023
1 parent 2e81392 commit 754b89e
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
echo "$HOME/.local/bin" >> $GITHUB_PATH
- run: cargo test -F $FEATURE
- run: cargo test -F $FEATURE --tests -- --ignored
- run: cargo test --manifest-path examples/Cargo.toml
- run: cargo test -F $FEATURE --manifest-path examples/Cargo.toml
- run: cargo build --manifest-path risc0/wasm/Cargo.toml --target wasm32-unknown-unknown
if: matrix.device == 'cpu'
- run: cargo check -F $FEATURE --benches
Expand Down
1 change: 1 addition & 0 deletions examples/chess/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ shakmaty = "0.22"

[features]
cuda = ["risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkvm/metal"]
30 changes: 30 additions & 0 deletions examples/chess/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,33 @@ fn main() {
pos.board()
);
}

#[cfg(test)]
mod tests {
use chess_core::Inputs;
use methods::{CHECKMATE_ELF, CHECKMATE_ID};
use risc0_zkvm::{serde::to_vec, Prover};

const TEST_BOARD: &str = "r1bqkb1r/pppp1ppp/2n2n2/4p2Q/2B1P3/8/PPPP1PPP/RNB1K1NR w KQkq - 4 4";
const TEST_MOVE: &str = "Qxf7";

#[test]
fn main() {
let inputs = Inputs {
board: String::from(TEST_BOARD),
mv: String::from(TEST_MOVE),
};

// Make the prover.
let mut prover = Prover::new(CHECKMATE_ELF, CHECKMATE_ID).unwrap();
prover.add_input_u32_slice(&to_vec(&inputs).expect("Should be serializable"));

// Run prover & generate receipt
let receipt = prover
.run()
.expect("Legal board state and checkmating move expected");

// Verify receipt and parse it for committed data
receipt.verify(&CHECKMATE_ID).unwrap();
}
}
5 changes: 3 additions & 2 deletions examples/digital-signature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ sha2 = "0.10"
ctor = "0.1"

[features]
cuda = ["risc0-zkvm/cuda"]
metal = ["risc0-zkvm/metal"]
cuda = ["risc0-zkp/cuda", "risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkp/metal", "risc0-zkvm/metal"]
26 changes: 26 additions & 0 deletions examples/digital-signature/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,29 @@ fn main() {
}
log::info!("\treceipt: valid");
}

#[cfg(test)]
mod tests {
use digital_signature::sign;
use sha2::{Digest, Sha256};

const MESSAGE: &str = "This is a signed message";
const PASSPHRASE: &str = "passw0rd";

#[test]
fn main() {
let signing_receipt = sign(&PASSPHRASE, &MESSAGE).unwrap();
let message_hash = &signing_receipt.get_message().unwrap().msg;
let expected_message_hash = Sha256::digest(MESSAGE);
assert_eq!(
message_hash,
expected_message_hash.as_slice(),
"Message commitment does not match given message!"
);
assert!(
signing_receipt.verify().is_ok(),
"Receipt is invalid! {}",
signing_receipt.verify().unwrap_err()
);
}
}
1 change: 1 addition & 0 deletions examples/factors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ serde = "1.0"

[features]
cuda = ["risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkvm/metal"]
5 changes: 3 additions & 2 deletions examples/json/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ risc0-zkvm = { path = "../../risc0/zkvm" }
serde = "1.0"

[features]
cuda = ["risc0-zkvm/cuda"]
metal = ["risc0-zkvm/metal"]
cuda = ["risc0-zkp/cuda", "risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkp/metal", "risc0-zkvm/metal"]
33 changes: 33 additions & 0 deletions examples/json/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,36 @@ fn main() {

println!("\nThe JSON file with hash\n {:?}\nprovably contains a field 'critical_data' with value {}\n", outputs.hash, outputs.data);
}

#[cfg(test)]
mod tests {
use json_core::Outputs;
use methods::{SEARCH_JSON_ELF, SEARCH_JSON_ID};
use risc0_zkvm::serde::{from_slice, to_vec};
use risc0_zkvm::Prover;

#[test]
fn main() {
let data = include_str!("../res/example.json");

// Make the prover.
let mut prover = Prover::new(SEARCH_JSON_ELF, SEARCH_JSON_ID)
.expect("Prover should be constructed from matching method code & ID");
prover.add_input_u32_slice(&to_vec(&data).expect("should be serializable"));

// Run prover & generate receipt
let receipt = prover.run().expect("Code should be provable");

receipt
.verify(&SEARCH_JSON_ID)
.expect("Proven code should verify");

let journal = &receipt.journal;
let outputs: Outputs =
from_slice(&journal).expect("Journal should contain an Outputs object");
assert_eq!(
outputs.data, 47,
"Did not find the expected value in the critical_data field"
);
}
}
5 changes: 5 additions & 0 deletions examples/password-checker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ methods = { path = "../methods" }
rand = "0.8"
risc0-zkp = { path = "../../risc0/zkp" }
risc0-zkvm = { path = "../../risc0/zkvm" }

[features]
cuda = ["risc0-zkp/cuda", "risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkp/metal", "risc0-zkvm/metal"]
29 changes: 29 additions & 0 deletions examples/password-checker/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,32 @@ fn main() {
// receipt is wrong
receipt.verify(&PW_CHECKER_ID).unwrap();
}

#[cfg(test)]
mod tests {
use methods::{PW_CHECKER_ELF, PW_CHECKER_ID};
use password_checker_core::PasswordRequest;
use risc0_zkvm::serde::to_vec;
use risc0_zkvm::Prover;

const TEST_SALT: [u8; 32] = [0u8; 32];
const TEST_PASSWORD: &str = "S00perSecr1t!!!";

#[test]
fn main() {
let request = PasswordRequest {
password: TEST_PASSWORD.into(),
salt: TEST_SALT,
};

// a new prover is created to run the pw_checker method
let mut prover = Prover::new(PW_CHECKER_ELF, PW_CHECKER_ID).unwrap();

// Adding input to the prover makes it readable by the guest
let vec = to_vec(&request).unwrap();
prover.add_input_u32_slice(&vec);

let receipt = prover.run().unwrap();
assert!(receipt.verify(&PW_CHECKER_ID).is_ok());
}
}
5 changes: 3 additions & 2 deletions examples/sha/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ methods = { path = "../methods" }
hex = "0.4"

[features]
cuda = ["risc0-zkvm/cuda"]
metal = ["risc0-zkvm/metal"]
cuda = ["risc0-zkp/cuda", "risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkp/metal", "risc0-zkvm/metal"]
5 changes: 5 additions & 0 deletions examples/wordle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ risc0-zkp = { path = "../../risc0/zkp" }
risc0-zkvm = { path = "../../risc0/zkvm" }
serde = "1.0"
wordle-core = { path = "core" }

[features]
cuda = ["risc0-zkp/cuda", "risc0-zkvm/cuda"]
default = []
metal = ["risc0-zkp/metal", "risc0-zkvm/metal"]
38 changes: 38 additions & 0 deletions examples/wordle/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use risc0_zkvm::serde::to_vec;
use risc0_zkvm::{Prover, Receipt};
use wordle_core::WORD_LENGTH;

#[cfg(test)]
use crate::wordlist::words::pick_fixed_word;
use crate::wordlist::words::pick_word;

mod wordlist;
Expand Down Expand Up @@ -51,6 +53,13 @@ impl Server<'_> {

return prover.run().unwrap();
}

#[cfg(test)]
pub fn new_for_testing() -> Self {
Self {
secret_word: pick_fixed_word(),
}
}
}

// The "player" is an agent in the Wordle game that tries to guess the server's
Expand Down Expand Up @@ -139,3 +148,32 @@ fn main() {
println!("Game over");
}
}

#[cfg(test)]
mod tests {

use crate::{game_is_won, Player, Server};

const TEST_GUESS_WRONG: &str = "roofs";
const TEST_GUESS_RIGHT: &str = "proof";

#[test]
fn main() {
let server = Server::new_for_testing();
let player = Player {
hash: server.get_secret_word_hash(),
};

let guess_word = TEST_GUESS_WRONG;
let receipt = server.check_round(&guess_word);
let score = player.check_receipt(receipt);
assert!(
!game_is_won(score),
"Incorrect guess should not win the game"
);
let guess_word = TEST_GUESS_RIGHT;
let receipt = server.check_round(&guess_word);
let score = player.check_receipt(receipt);
assert!(game_is_won(score), "Correct guess should win the game");
}
}
5 changes: 5 additions & 0 deletions examples/wordle/src/wordlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,9 @@ pub mod words {
pub fn pick_word() -> &'static str {
return WORDS.choose(&mut rand::thread_rng()).unwrap();
}

#[cfg(test)]
pub fn pick_fixed_word() -> &'static str {
return "proof";
}
}

0 comments on commit 754b89e

Please sign in to comment.