Set up basic client/server interaction.
This commit is contained in:
parent
96f05c11a4
commit
eeb627aff7
|
@ -23,6 +23,8 @@ extern "C" void decrypt_solution(uint32_t n, uint8_t *enc, unsigned char* key) {
|
|||
}
|
||||
|
||||
extern "C" void mysnark_init_public_params() {
|
||||
libsnark::inhibit_profiling_info = true;
|
||||
libsnark::inhibit_profiling_counters = true;
|
||||
default_r1cs_ppzksnark_pp::init_public_params();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
fn decrypt_solution(n: uint32_t, enc: *mut uint8_t, key: *const uint8_t);
|
||||
fn snark_verify(keypair: *const Keypair,
|
||||
n: uint32_t,
|
||||
proof: *const c_char,
|
||||
proof: *const uint8_t,
|
||||
proof_len: int32_t,
|
||||
puzzle: *const uint8_t,
|
||||
h_of_key: *const uint8_t,
|
||||
|
@ -89,8 +89,8 @@ pub fn get_context(pk: &[u8], vk: &[u8], n: usize) -> Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn prove<F: for<'a> FnMut(&'a [u8], &'a [i8])>(ctx: Context, puzzle: &[u8], solution: &[u8], key: &[u8], h_of_key: &[u8], mut f: F) -> bool {
|
||||
let mut cb: &mut for<'a> FnMut(&'a [u8], &'a [i8]) = &mut f;
|
||||
pub fn prove<F: for<'a> FnMut(&'a [u8], &'a [u8])>(ctx: &Context, puzzle: &[u8], solution: &[u8], key: &[u8], h_of_key: &[u8], mut f: F) -> bool {
|
||||
let mut cb: &mut for<'a> FnMut(&'a [u8], &'a [u8]) = &mut f;
|
||||
|
||||
let cells = ctx.n.pow(4);
|
||||
assert_eq!(puzzle.len(), cells);
|
||||
|
@ -110,7 +110,7 @@ pub fn decrypt(ctx: Context, enc_solution: &mut [u8], key: &[u8])
|
|||
unsafe { decrypt_solution(ctx.n as u32, &mut enc_solution[0], &key[0]); }
|
||||
}
|
||||
|
||||
pub fn verify(ctx: Context, proof: &[i8], puzzle: &[u8], h_of_key: &[u8], encrypted_solution: &[u8]) -> bool
|
||||
pub fn verify(ctx: &Context, proof: &[u8], puzzle: &[u8], h_of_key: &[u8], encrypted_solution: &[u8]) -> bool
|
||||
{
|
||||
assert_eq!(ctx.n.pow(4), encrypted_solution.len());
|
||||
assert_eq!(ctx.n.pow(4), puzzle.len());
|
||||
|
|
127
src/main.rs
127
src/main.rs
|
@ -58,6 +58,18 @@ fn main() {
|
|||
.required(true)
|
||||
.validator(is_number))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("serve")
|
||||
.about("Opens a server for paying people to solve sudoku puzzles")
|
||||
.arg(Arg::with_name("n")
|
||||
.required(true)
|
||||
.validator(is_number))
|
||||
)
|
||||
.subcommand(SubCommand::with_name("client")
|
||||
.about("Connects to a server to receive payment to solve sudoku puzzles")
|
||||
.arg(Arg::with_name("n")
|
||||
.required(true)
|
||||
.validator(is_number))
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("gen") {
|
||||
|
@ -74,6 +86,54 @@ fn main() {
|
|||
});
|
||||
}
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("client") {
|
||||
println!("Loading proving/verifying keys...");
|
||||
let n: usize = matches.value_of("n").unwrap().parse().unwrap();
|
||||
|
||||
let ctx = {
|
||||
println!("\tProving key...");
|
||||
let pk = decompress(&format!("{}.pk", n));
|
||||
println!("\tVerifying key...");
|
||||
let vk = decompress(&format!("{}.vk", n));
|
||||
|
||||
println!("\tDeserializing...");
|
||||
|
||||
get_context(&pk, &vk, n)
|
||||
};
|
||||
|
||||
let mut stream = TcpStream::connect("127.0.0.1:25519").unwrap();
|
||||
|
||||
handle_server(&mut stream, &ctx, n);
|
||||
}
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("serve") {
|
||||
println!("Loading proving/verifying keys...");
|
||||
let n: usize = matches.value_of("n").unwrap().parse().unwrap();
|
||||
|
||||
let ctx = {
|
||||
println!("\tProving key...");
|
||||
let pk = decompress(&format!("{}.pk", n));
|
||||
println!("\tVerifying key...");
|
||||
let vk = decompress(&format!("{}.vk", n));
|
||||
|
||||
println!("\tDeserializing...");
|
||||
|
||||
get_context(&pk, &vk, n)
|
||||
};
|
||||
|
||||
let listener = TcpListener::bind("0.0.0.0:25519").unwrap();
|
||||
println!("Opened listener. Instruct client to connect.");
|
||||
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(mut stream) => {
|
||||
handle_client(&mut stream, &ctx, n);
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
println!("Loading proving/verifying keys...");
|
||||
let n: usize = matches.value_of("n").unwrap().parse().unwrap();
|
||||
|
@ -103,12 +163,77 @@ fn main() {
|
|||
|
||||
println!("Generating proof...");
|
||||
|
||||
assert!(prove(ctx, &puzzle, &solution, &key, &h_of_key,
|
||||
assert!(prove(&ctx, &puzzle, &solution, &key, &h_of_key,
|
||||
|encrypted_solution, proof| {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_client(stream: &mut TcpStream, ctx: &Context, n: usize) -> Result<(), ProtoError> {
|
||||
println!("Connected!");
|
||||
|
||||
println!("Generating puzzle...");
|
||||
let puzzle = Sudoku::gen(n);
|
||||
|
||||
try!(serialize_into(stream, &puzzle, Infinite));
|
||||
|
||||
println!("Waiting for proof that the client has a solution...");
|
||||
|
||||
let proof: Cow<[u8]> = deserialize_from(stream, Infinite).unwrap();
|
||||
let encrypted_solution: Cow<[u8]> = deserialize_from(stream, Infinite).unwrap();
|
||||
let mut h_of_key: Vec<u8> = deserialize_from(stream, Infinite).unwrap();
|
||||
|
||||
println!("Verifying proof.");
|
||||
|
||||
if (!verify(ctx, &proof, &puzzle, &h_of_key, &encrypted_solution)) {
|
||||
println!("Proof is invalid!");
|
||||
|
||||
return Err(ProtoError);
|
||||
}
|
||||
|
||||
println!("Proof verified!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_server(stream: &mut TcpStream, ctx: &Context, n: usize) -> Result<(), ProtoError> {
|
||||
println!("Waiting for server to give us a puzzle...");
|
||||
let puzzle: Vec<u8> = deserialize_from(stream, Infinite).unwrap();
|
||||
|
||||
println!("Received puzzle:");
|
||||
print_sudoku(n*n, &puzzle);
|
||||
|
||||
println!("Solving puzzle...");
|
||||
let solution: Vec<u8> = Sudoku::import_and_solve(n, &puzzle).unwrap();
|
||||
print_sudoku(n*n, &solution);
|
||||
|
||||
let key = vec![206, 64, 25, 10, 245, 205, 246, 107, 191, 157, 114, 181, 63, 40, 95, 134, 6, 178, 210, 43, 243, 10, 217, 251, 246, 248, 0, 21, 86, 194, 100, 94];
|
||||
let h_of_key = vec![253, 199, 66, 55, 24, 155, 80, 121, 138, 60, 36, 201, 186, 221, 164, 65, 194, 53, 192, 159, 252, 7, 194, 24, 200, 217, 57, 55, 45, 204, 71, 9];
|
||||
|
||||
println!("Generating proof...");
|
||||
|
||||
assert!(prove(ctx, &puzzle, &solution, &key, &h_of_key, |encrypted_solution, proof| {
|
||||
println!("Sending proof, encrypted_solution and h_of_key to the server.");
|
||||
|
||||
let encrypted_solution = Cow::Borrowed(encrypted_solution);
|
||||
let proof = Cow::Borrowed(proof);
|
||||
|
||||
serialize_into(stream, &proof, Infinite);
|
||||
serialize_into(stream, &encrypted_solution, Infinite);
|
||||
serialize_into(stream, &h_of_key, Infinite);
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct ProtoError;
|
||||
|
||||
impl From<bincode::serde::SerializeError> for ProtoError {
|
||||
fn from(a: bincode::serde::SerializeError) -> ProtoError {
|
||||
ProtoError
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn main() {
|
||||
initialize();
|
||||
|
|
|
@ -80,7 +80,7 @@ pub struct Sudoku {
|
|||
}
|
||||
|
||||
impl Sudoku {
|
||||
pub fn gen(n: usize) -> Vec<usize> {
|
||||
pub fn gen(n: usize) -> Vec<u8> {
|
||||
use rand::thread_rng;
|
||||
let mut rng = thread_rng();
|
||||
|
||||
|
@ -90,7 +90,7 @@ impl Sudoku {
|
|||
grid.export()
|
||||
}
|
||||
|
||||
pub fn import_and_solve(n: usize, puzzle: &[usize]) -> Option<Vec<usize>> {
|
||||
pub fn import_and_solve(n: usize, puzzle: &[u8]) -> Option<Vec<u8>> {
|
||||
use rand::thread_rng;
|
||||
let mut rng = thread_rng();
|
||||
|
||||
|
@ -136,21 +136,21 @@ impl Sudoku {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn inject(&self, other: &[usize]) {
|
||||
pub fn inject(&self, other: &[u8]) {
|
||||
for (i, &to) in other.iter().enumerate() {
|
||||
if to != 0 {
|
||||
self.cells[i].set(to);
|
||||
self.cells[i].set(to as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn export(&self) -> Vec<usize> {
|
||||
pub fn export(&self) -> Vec<u8> {
|
||||
let mut acc = vec![];
|
||||
|
||||
for i in 0..(self.dimension * self.dimension) {
|
||||
match self.cells[i].get() {
|
||||
Some(val) => {
|
||||
acc.push(val);
|
||||
acc.push(val as u8);
|
||||
},
|
||||
None => {
|
||||
acc.push(0);
|
||||
|
@ -231,7 +231,7 @@ impl Sudoku {
|
|||
|
||||
pub fn clearsome<R: Rng>(&mut self, rng: &mut R) {
|
||||
for i in 0..(self.dimension * self.dimension) {
|
||||
if rng.gen_weighted_bool(5) {
|
||||
if rng.gen_weighted_bool(2) {
|
||||
self.cells[i].unset();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue