Skip to content

Commit

Permalink
Adding zkp sources
Browse files Browse the repository at this point in the history
  • Loading branch information
John Basrai authored and John Basrai committed Oct 3, 2023
1 parent 092eae3 commit ab4b34a
Show file tree
Hide file tree
Showing 10 changed files with 659 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# will have compiled files and executables
debug/
target/
src/zkp_auth.rs

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Expand Down
25 changes: 25 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "zkp-chaum-pedersen"
version = "0.1.0"
edition = "2021"

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

[dependencies]
rand = "0.8"
num-bigint = { version = "0.4", features = ["rand"] }
hex = "0.4.3"
tonic = "0.9"
prost = "0.11"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } # async rust runtime

[build-dependencies]
tonic-build = "0.9"

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

[[bin]]
name = "client"
path = "./src/client.rs"
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# zkp-cp
Chaum-Pedersen Zero Knowledge Proof
# Chaum-Pedersen Zero Knowledge Proof
# gRPC client/server for authentication

Rust crates directly used

- tokio, Rusts asynchronous runtime.

Tokio is a tool that provides the building blocks for writing network
applications without compromising speed. It includes a stack of
various components, such as Hyper, Tonic, Tower, and Mio, for
different needs and scenarios.

- tonic - gRPC, Rust implementation of gRPC

## Building

```
cargo build --release --bin client --bin server
```

## Running

In one shell window run command
```
cargo run --release --bin server
```
In a second shell window run command
```
cargo run --release --bin client
```

## Containerization

Work in progress.

11 changes: 11 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main()
{
tonic_build::configure()
.build_server(true)
.out_dir("src/") // you can change the generated code's location
.compile(
&["proto/zkp_auth.proto"],
&["proto/"], // specify the root location to search proto dependencies
)
.unwrap();
}
51 changes: 51 additions & 0 deletions proto/zkp_auth.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
syntax = "proto3";
package zkp_auth;

/*
* Prover registers in the server sending:
* y1 = alpha^x mod p
* y2 = beta^x mod p
*/
message RegisterRequest {
string user = 1;
bytes y1 = 2;
bytes y2 = 3;
}

message RegisterResponse {}

/*
* Prover ask for challenge in the server sending
* r1 = alpha^k mod p
* r2 = beta^k mod p
* Verifier sends the challenge "c" back
*/
message AuthenticationChallengeRequest {
string user = 1;
bytes r1 = 2;
bytes r2 = 3;
}

message AuthenticationChallengeResponse {
string auth_id = 1;
bytes c = 2;
}

/*
* Prover sends solution "s = k - c * x mod q" to the challenge
* Verifier sends the session ID if the solution is correct
*/
message AuthenticationAnswerRequest {
string auth_id = 1;
bytes s = 2;
}

message AuthenticationAnswerResponse {
string session_id = 1;
}

service Auth {
rpc Register(RegisterRequest) returns (RegisterResponse) {}
rpc CreateAuthenticationChallenge(AuthenticationChallengeRequest) returns (AuthenticationChallengeResponse) {}
rpc VerifyAuthentication(AuthenticationAnswerRequest) returns (AuthenticationAnswerResponse) {}
}
2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
19 changes: 19 additions & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
edition = "2021"

array_width = 70
fn_params_layout = "Compressed"
fn_call_width = 80
fn_single_line = true
space_before_colon = false
spaces_around_ranges = true
unstable_features = true

wrap_comments = true
max_width = 100
comment_width = 90

# These work only for nightly builds (of rust toolchain), as of rust v 1.71
control_brace_style = "AlwaysNextLine"
brace_style = "AlwaysNextLine"
struct_field_align_threshold = 40
enum_discrim_align_threshold = 40
95 changes: 95 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use num_bigint::BigUint;
use std::io::stdin;

pub mod zkp_auth
{
include!("./zkp_auth.rs");
}

use zkp_auth::{
auth_client::AuthClient, AuthenticationAnswerRequest, AuthenticationChallengeRequest,
RegisterRequest,
};
use zkp_chaum_pedersen::ZKP;

#[tokio::main]
async fn main()
{
let mut buf = String::new();
let (alpha, beta, p, q) = ZKP::get_constants();
let zkp = ZKP::new(&alpha, &beta, &p, &q);

let mut client = AuthClient::connect("http://127.0.0.1:50051")
.await
.expect("could not connect to the server");
println!("✅ Connected to the server");

println!("Please provide the username:");
stdin()
.read_line(&mut buf)
.expect("Could not get the username from stdin");
let username = buf.trim().to_string();
buf.clear();

println!("Please provide the password:");
stdin()
.read_line(&mut buf)
.expect("Could not get the username from stdin");
let password = BigUint::from_bytes_be(buf.trim().as_bytes());
buf.clear();

let (y1, y2) = zkp.compute_pair(&password);

let request = RegisterRequest {
user: username.clone(),
y1: y1.to_bytes_be(),
y2: y2.to_bytes_be(),
};

let _response = client
.register(request)
.await
.expect("Could not register in server");

println!("✅ Registration was successful");

println!("Please provide the password (to login):");
stdin()
.read_line(&mut buf)
.expect("Could not get the username from stdin");
let password = BigUint::from_bytes_be(buf.trim().as_bytes());
buf.clear();

let k = ZKP::generate_random_number_below(&q);
let (r1, r2) = zkp.compute_pair(&k);

let request = AuthenticationChallengeRequest {
user: username,
r1: r1.to_bytes_be(),
r2: r2.to_bytes_be(),
};

let response = client
.create_authentication_challenge(request)
.await
.expect("Could not request challenge to server")
.into_inner();

let auth_id = response.auth_id;
let c = BigUint::from_bytes_be(&response.c);

let s = zkp.solve(&k, &c, &password);

let request = AuthenticationAnswerRequest {
auth_id,
s: s.to_bytes_be(),
};

let response = client
.verify_authentication(request)
.await
.expect("Could not verify authentication in server")
.into_inner();

println!("✅Logging successful! session_id: {}", response.session_id);
}
Loading

0 comments on commit ab4b34a

Please sign in to comment.