mirror of https://github.com/zcash/mpc.git
Added public verifier tool.
This commit is contained in:
parent
84cee5476d
commit
5f50eea70d
|
@ -2,3 +2,4 @@ target
|
||||||
r1cs
|
r1cs
|
||||||
pk
|
pk
|
||||||
vk
|
vk
|
||||||
|
transcript
|
||||||
|
|
|
@ -15,6 +15,12 @@ path = "src/coordinator.rs"
|
||||||
# avoid duplicate tests
|
# avoid duplicate tests
|
||||||
test = false
|
test = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "verifier"
|
||||||
|
path = "src/verifier.rs"
|
||||||
|
# avoid duplicate tests
|
||||||
|
test = false
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "player"
|
name = "player"
|
||||||
path = "src/player.rs"
|
path = "src/player.rs"
|
||||||
|
|
|
@ -32,10 +32,11 @@ use bincode::SizeLimit::Infinite;
|
||||||
use bincode::rustc_serialize::{encode_into, decode_from};
|
use bincode::rustc_serialize::{encode_into, decode_from};
|
||||||
use std::time::Duration;
|
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 NETWORK_MAGIC: [u8; 8] = [0xff, 0xff, 0x1f, 0xbb, 0x1c, 0xee, 0x00, 0x19];
|
||||||
const PLAYERS: usize = 3;
|
const PLAYERS: usize = 2;
|
||||||
pub const THREADS: usize = 128;
|
pub const THREADS: usize = 8;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct ConnectionHandler {
|
struct ConnectionHandler {
|
||||||
|
@ -105,9 +106,21 @@ impl ConnectionHandler {
|
||||||
|
|
||||||
fn run(&self, new_peers: Receiver<[u8; 8]>)
|
fn run(&self, new_peers: Receiver<[u8; 8]>)
|
||||||
{
|
{
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
info!("Loading R1CS from disk and performing QAP reduction...");
|
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...");
|
info!("Waiting for players to connect...");
|
||||||
|
|
||||||
|
@ -117,9 +130,13 @@ impl ConnectionHandler {
|
||||||
for peerid in new_peers.into_iter().take(PLAYERS) {
|
for peerid in new_peers.into_iter().take(PLAYERS) {
|
||||||
info!("Initializing new player (peerid={})", peerid.to_hex());
|
info!("Initializing new player (peerid={})", peerid.to_hex());
|
||||||
info!("Asking for commitment to PublicKey (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());
|
info!("PublicKey Commitment received (peerid={})", peerid.to_hex());
|
||||||
peers.push(peerid);
|
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`.
|
// The remote end should never hang up, so this should always be `PLAYERS`.
|
||||||
|
@ -135,10 +152,15 @@ impl ConnectionHandler {
|
||||||
|
|
||||||
self.write(peerid, &stage1);
|
self.write(peerid, &stage1);
|
||||||
|
|
||||||
info!("Receiving stage1 transformation from peerid={}", peerid.to_hex());
|
info!("Receiving public key from peerid={}", peerid.to_hex());
|
||||||
|
|
||||||
// TODO: verify pubkey against comm
|
|
||||||
let pubkey = self.read::<PublicKey>(peerid);
|
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);
|
let new_stage1 = self.read::<Stage1Contents>(peerid);
|
||||||
|
|
||||||
info!("Verifying transformation of stage1 from peerid={}", peerid.to_hex());
|
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());
|
error!("Peer did not perform valid stage1 transformation (peerid={})", peerid.to_hex());
|
||||||
panic!("cannot recover.");
|
panic!("cannot recover.");
|
||||||
} else {
|
} 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);
|
pubkeys.push(pubkey);
|
||||||
stage1 = new_stage1;
|
stage1 = new_stage1;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +197,8 @@ impl ConnectionHandler {
|
||||||
error!("Peer did not perform valid stage2 transformation (peerid={})", peerid.to_hex());
|
error!("Peer did not perform valid stage2 transformation (peerid={})", peerid.to_hex());
|
||||||
panic!("cannot recover.");
|
panic!("cannot recover.");
|
||||||
} else {
|
} else {
|
||||||
|
info!("Writing new stage2 to transcript");
|
||||||
|
encode_into(&new_stage2, &mut transcript, Infinite).unwrap();
|
||||||
stage2 = new_stage2;
|
stage2 = new_stage2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +221,8 @@ impl ConnectionHandler {
|
||||||
error!("Peer did not perform valid stage3 transformation (peerid={})", peerid.to_hex());
|
error!("Peer did not perform valid stage3 transformation (peerid={})", peerid.to_hex());
|
||||||
panic!("cannot recover.");
|
panic!("cannot recover.");
|
||||||
} else {
|
} else {
|
||||||
|
info!("Writing new stage3 to transcript");
|
||||||
|
encode_into(&new_stage3, &mut transcript, Infinite).unwrap();
|
||||||
stage3 = new_stage3;
|
stage3 = new_stage3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,6 +234,10 @@ impl ConnectionHandler {
|
||||||
kp.write_to_disk();
|
kp.write_to_disk();
|
||||||
|
|
||||||
info!("Keypair written to disk.");
|
info!("Keypair written to disk.");
|
||||||
|
|
||||||
|
transcript.flush().unwrap();
|
||||||
|
|
||||||
|
info!("Transcript flushed to disk.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept(&self, peerid: [u8; 8], stream: TcpStream) {
|
fn accept(&self, peerid: [u8; 8], stream: TcpStream) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use std::time::Duration;
|
||||||
use bincode::SizeLimit::Infinite;
|
use bincode::SizeLimit::Infinite;
|
||||||
use bincode::rustc_serialize::{encode_into, decode_from};
|
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];
|
const NETWORK_MAGIC: [u8; 8] = [0xff, 0xff, 0x1f, 0xbb, 0x1c, 0xee, 0x00, 0x19];
|
||||||
pub const THREADS: usize = 8;
|
pub const THREADS: usize = 8;
|
||||||
|
|
||||||
|
@ -113,9 +113,7 @@ fn main() {
|
||||||
let privkey = PrivateKey::new(rng);
|
let privkey = PrivateKey::new(rng);
|
||||||
let pubkey = privkey.pubkey(rng);
|
let pubkey = privkey.pubkey(rng);
|
||||||
|
|
||||||
let commitment: [u8; 32] = [0; 32];
|
let commitment = pubkey.hash();
|
||||||
|
|
||||||
// TODO
|
|
||||||
handler.write(&commitment);
|
handler.write(&commitment);
|
||||||
|
|
||||||
// Get powers of tau.
|
// Get powers of tau.
|
||||||
|
|
|
@ -5,6 +5,8 @@ use spair::*;
|
||||||
use snark::*;
|
use snark::*;
|
||||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||||
|
|
||||||
|
pub type PublicKeyHash = [u8; 32];
|
||||||
|
|
||||||
pub struct PublicKey {
|
pub struct PublicKey {
|
||||||
f1: G2, // f1
|
f1: G2, // f1
|
||||||
f1pA: G2, // f1 * rho_a
|
f1pA: G2, // f1 * rho_a
|
||||||
|
@ -41,6 +43,11 @@ impl PublicKey {
|
||||||
same_power(&self.gamma, &Spair::new(self.f2beta, self.f2betagamma).unwrap())
|
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> {
|
pub fn tau_g2(&self) -> Spair<G2> {
|
||||||
self.tau.clone()
|
self.tau.clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
Loading…
Reference in New Issue