Added public verifier tool.

This commit is contained in:
Sean Bowe 2016-09-16 17:11:46 -06:00
parent 84cee5476d
commit 5f50eea70d
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
6 changed files with 146 additions and 12 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ target
r1cs
pk
vk
transcript

View File

@ -15,6 +15,12 @@ path = "src/coordinator.rs"
# avoid duplicate tests
test = false
[[bin]]
name = "verifier"
path = "src/verifier.rs"
# avoid duplicate tests
test = false
[[bin]]
name = "player"
path = "src/player.rs"

View File

@ -32,10 +32,11 @@ use bincode::SizeLimit::Infinite;
use bincode::rustc_serialize::{encode_into, decode_from};
use std::time::Duration;
const LISTEN_ADDR: &'static str = "0.0.0.0:65530";
const USE_DUMMY_CS: bool = true;
const LISTEN_ADDR: &'static str = "127.0.0.1:65530";
const NETWORK_MAGIC: [u8; 8] = [0xff, 0xff, 0x1f, 0xbb, 0x1c, 0xee, 0x00, 0x19];
const PLAYERS: usize = 3;
pub const THREADS: usize = 128;
const PLAYERS: usize = 2;
pub const THREADS: usize = 8;
#[derive(Clone)]
struct ConnectionHandler {
@ -105,9 +106,21 @@ impl ConnectionHandler {
fn run(&self, new_peers: Receiver<[u8; 8]>)
{
use std::fs::File;
info!("Loading R1CS from disk and performing QAP reduction...");
let cs = CS::from_file();
let cs = {
if USE_DUMMY_CS {
CS::dummy()
} else {
CS::from_file()
}
};
info!("Creating transcript file...");
let mut transcript = File::create("transcript").unwrap();
encode_into(&PLAYERS, &mut transcript, Infinite).unwrap();
info!("Waiting for players to connect...");
@ -117,9 +130,13 @@ impl ConnectionHandler {
for peerid in new_peers.into_iter().take(PLAYERS) {
info!("Initializing new player (peerid={})", peerid.to_hex());
info!("Asking for commitment to PublicKey (peerid={})", peerid.to_hex());
commitments.push(self.read(&peerid));
let comm = self.read(&peerid);
commitments.push(comm);
info!("PublicKey Commitment received (peerid={})", peerid.to_hex());
peers.push(peerid);
info!("Writing commitment to transcript");
encode_into(&comm, &mut transcript, Infinite).unwrap();
}
// The remote end should never hang up, so this should always be `PLAYERS`.
@ -135,10 +152,15 @@ impl ConnectionHandler {
self.write(peerid, &stage1);
info!("Receiving stage1 transformation from peerid={}", peerid.to_hex());
// TODO: verify pubkey against comm
info!("Receiving public key from peerid={}", peerid.to_hex());
let pubkey = self.read::<PublicKey>(peerid);
if pubkey.hash() != *comm {
error!("Peer did not properly commit to their public key (peerid={})", peerid.to_hex());
panic!("cannot recover.");
}
info!("Receiving stage1 transformation from peerid={}", peerid.to_hex());
let new_stage1 = self.read::<Stage1Contents>(peerid);
info!("Verifying transformation of stage1 from peerid={}", peerid.to_hex());
@ -147,6 +169,11 @@ impl ConnectionHandler {
error!("Peer did not perform valid stage1 transformation (peerid={})", peerid.to_hex());
panic!("cannot recover.");
} else {
info!("Writing `PublicKey` to transcript");
encode_into(&pubkey, &mut transcript, Infinite).unwrap();
info!("Writing new stage1 to transcript");
encode_into(&new_stage1, &mut transcript, Infinite).unwrap();
pubkeys.push(pubkey);
stage1 = new_stage1;
}
@ -170,6 +197,8 @@ impl ConnectionHandler {
error!("Peer did not perform valid stage2 transformation (peerid={})", peerid.to_hex());
panic!("cannot recover.");
} else {
info!("Writing new stage2 to transcript");
encode_into(&new_stage2, &mut transcript, Infinite).unwrap();
stage2 = new_stage2;
}
}
@ -192,6 +221,8 @@ impl ConnectionHandler {
error!("Peer did not perform valid stage3 transformation (peerid={})", peerid.to_hex());
panic!("cannot recover.");
} else {
info!("Writing new stage3 to transcript");
encode_into(&new_stage3, &mut transcript, Infinite).unwrap();
stage3 = new_stage3;
}
}
@ -203,6 +234,10 @@ impl ConnectionHandler {
kp.write_to_disk();
info!("Keypair written to disk.");
transcript.flush().unwrap();
info!("Transcript flushed to disk.");
}
fn accept(&self, peerid: [u8; 8], stream: TcpStream) {

View File

@ -25,7 +25,7 @@ use std::time::Duration;
use bincode::SizeLimit::Infinite;
use bincode::rustc_serialize::{encode_into, decode_from};
const COORDINATOR_ADDR: &'static str = "testrun.z.cash:65530";
const COORDINATOR_ADDR: &'static str = "127.0.0.1:65530";
const NETWORK_MAGIC: [u8; 8] = [0xff, 0xff, 0x1f, 0xbb, 0x1c, 0xee, 0x00, 0x19];
pub const THREADS: usize = 8;
@ -113,9 +113,7 @@ fn main() {
let privkey = PrivateKey::new(rng);
let pubkey = privkey.pubkey(rng);
let commitment: [u8; 32] = [0; 32];
// TODO
let commitment = pubkey.hash();
handler.write(&commitment);
// Get powers of tau.

View File

@ -5,6 +5,8 @@ use spair::*;
use snark::*;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
pub type PublicKeyHash = [u8; 32];
pub struct PublicKey {
f1: G2, // f1
f1pA: G2, // f1 * rho_a
@ -41,6 +43,11 @@ impl PublicKey {
same_power(&self.gamma, &Spair::new(self.f2beta, self.f2betagamma).unwrap())
}
pub fn hash(&self) -> PublicKeyHash {
// TODO
[0xff; 32]
}
pub fn tau_g2(&self) -> Spair<G2> {
self.tau.clone()
}

87
src/verifier.rs Normal file
View File

@ -0,0 +1,87 @@
extern crate bn;
extern crate rand;
extern crate snark;
extern crate crossbeam;
extern crate rustc_serialize;
extern crate bincode;
mod multicore;
mod qap;
mod protocol;
mod spair;
use std::fs::File;
use std::io::{Read, Write};
use protocol::*;
use snark::*;
use bincode::SizeLimit::Infinite;
use bincode::rustc_serialize::{encode_into, decode_from};
const USE_DUMMY_CS: bool = true;
pub const THREADS: usize = 8;
fn main() {
let mut f = File::open("transcript").unwrap();
let cs = {
if USE_DUMMY_CS {
CS::dummy()
} else {
CS::from_file()
}
};
let num_players: usize = decode_from(&mut f, Infinite).unwrap();
println!("Number of players: {}", num_players);
let mut commitments = vec![];
let mut pubkeys = vec![];
for i in 0..num_players {
let comm: [u8; 32] = decode_from(&mut f, Infinite).unwrap();
commitments.push(comm);
}
let mut stage1 = Stage1Contents::new(&cs);
for i in 0..num_players {
let pubkey: PublicKey = decode_from(&mut f, Infinite).unwrap();
if pubkey.hash() != commitments[i] {
panic!("Invalid commitment from player {}", i);
}
let new_stage: Stage1Contents = decode_from(&mut f, Infinite).unwrap();
if !new_stage.verify_transform(&stage1, &pubkey) {
panic!("Invalid stage1 transformation from player {}", i);
}
stage1 = new_stage;
pubkeys.push(pubkey);
}
let mut stage2 = Stage2Contents::new(&cs, &stage1);
for i in 0..num_players {
let new_stage: Stage2Contents = decode_from(&mut f, Infinite).unwrap();
if !new_stage.verify_transform(&stage2, &pubkeys[i]) {
panic!("Invalid stage2 transformation from player {}", i);
}
stage2 = new_stage;
}
let mut stage3 = Stage3Contents::new(&stage2);
for i in 0..num_players {
let new_stage: Stage3Contents = decode_from(&mut f, Infinite).unwrap();
if !new_stage.verify_transform(&stage3, &pubkeys[i]) {
panic!("Invalid stage3 transformation from player {}", i);
}
stage3 = new_stage;
}
let kp = keypair(&cs, &stage1, &stage2, &stage3);
kp.write_to_disk();
}