Skip to content

Commit

Permalink
Add password_checker example
Browse files Browse the repository at this point in the history
  • Loading branch information
Vesnica committed Aug 16, 2022
1 parent 2e3afcd commit 364b422
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 0 deletions.
9 changes: 9 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ risc0-zkvm = "0.11.1"
risc0-zkp = { version = "0.11.1", default-features = false }
confy = "0.4"
sha2 = "0.10.2"
rand = { version = "0.8.5", default-features = false }

[[bin]]
name = "prover_add"
Expand All @@ -34,3 +35,11 @@ path = "src/prover_sig.rs"
[[bin]]
name = "verifier_sig"
path = "src/verifier_sig.rs"

[[bin]]
name = "prover_pw"
path = "src/prover_pw.rs"

[[bin]]
name = "verifier_pw"
path = "src/verifier_pw.rs"
33 changes: 33 additions & 0 deletions cli/src/prover_pw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use common::{encode_hex_u32, encode_hex_u8, PasswordRequest, Proof};
use methods::{PASSWORD_ELF, PASSWORD_ID};
use rand::{thread_rng, RngCore};
use risc0_zkp::core::sha::Digest;
use risc0_zkvm::host::Prover;
use risc0_zkvm::serde::{from_slice, to_vec};

fn main() {
let mut rng = thread_rng();
let mut salt = [0u8; 32];
rng.fill_bytes(&mut salt);

let request = PasswordRequest {
password: "S00perSecr1t!!!".into(),
salt,
};

let mut prover = Prover::new(PASSWORD_ELF, PASSWORD_ID).unwrap();

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

let receipt = prover.run().unwrap();
let password_hash: Digest = from_slice(&receipt.get_journal_vec().unwrap()).unwrap();
println!("Password hash is: {}", &password_hash);

let proof = Proof {
journal: encode_hex_u8(receipt.get_journal().unwrap()),
seal: encode_hex_u32(receipt.get_seal().unwrap()),
};
confy::store_path("./proof.toml", proof).unwrap();
}
14 changes: 14 additions & 0 deletions cli/src/verifier_pw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use common::{decode_hex_u32, decode_hex_u8, Proof};
use methods::PASSWORD_ID;
use risc0_zkvm::host::Receipt;

fn main() {
let proof: Proof = confy::load_path("./proof.toml").unwrap();
let journal = decode_hex_u8(&proof.journal).unwrap();
let seal = decode_hex_u32(&proof.seal).unwrap();
let receipt = Receipt::new(&journal, &seal).unwrap();
match receipt.verify(PASSWORD_ID) {
Ok(_) => println!("Verified OK!"),
Err(_) => println!("Verify Failed!"),
};
}
6 changes: 6 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ pub struct SignMessageCommit {
pub identity: Digest,
pub msg: Message,
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PasswordRequest {
pub password: String,
pub salt: [u8; 32],
}
3 changes: 3 additions & 0 deletions methods/guest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ risc0-build = "0.11.1"
common = { path = "../../common" }
risc0-zkvm-guest = "0.11.1"

[profile.release]
lto = true
opt-level = "z"
91 changes: 91 additions & 0 deletions methods/guest/src/bin/password.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#![no_main]
#![no_std]

use common::PasswordRequest;
use risc0_zkvm_guest::{env, sha};

risc0_zkvm_guest::entry!(main);

struct PasswordPolicy {
pub min_length: usize,
pub max_length: usize,
pub min_uppercase: usize,
pub min_lowercase: usize,
pub min_numeric: usize,
pub min_special_chars: usize,
}

impl PasswordPolicy {
pub fn is_valid(&self, pw: &str) -> bool {
let metrics = PasswordMetrics::new(pw);
self.correct_length(pw)
&& (metrics.numeric >= self.min_numeric)
&& (metrics.uppercase >= self.min_uppercase)
&& (metrics.lowercase >= self.min_lowercase)
&& (metrics.special >= self.min_special_chars)
}

fn correct_length(&self, password: &str) -> bool {
password.len() > (self.min_length - 1) && password.len() < (self.max_length + 1)
}
}

struct PasswordMetrics {
pub numeric: usize,
pub special: usize,
pub uppercase: usize,
pub lowercase: usize,
}

impl PasswordMetrics {
pub fn new(password: &str) -> Self {
let mut numeric = 0;
let mut special = 0;
let mut uppercase = 0;
let mut lowercase = 0;
for ch in password.chars() {
if ch.is_ascii_digit() {
numeric += 1;
}
if ch.is_ascii_punctuation() {
special += 1;
}
if ch.is_ascii_uppercase() {
uppercase += 1;
}
if ch.is_ascii_lowercase() {
lowercase += 1;
}
}
PasswordMetrics {
numeric,
special,
uppercase,
lowercase,
}
}
}

pub fn main() {
let request: PasswordRequest = env::read();

let policy = PasswordPolicy {
min_length: 3,
max_length: 64,
min_numeric: 2,
min_uppercase: 2,
min_lowercase: 2,
min_special_chars: 1,
};

if !policy.is_valid(&request.password) {
panic!("Password invalid. Please try again.");
}

let mut salted_password = request.password.as_bytes().to_vec();
salted_password.extend(request.salt);
let password_hash = sha::digest_u8_slice(&salted_password[..]);

env::commit(&password_hash);
env::commit(&request.salt);
}

0 comments on commit 364b422

Please sign in to comment.