diff --git a/jcli/src/jcli_app/vote/decrypt_shares.rs b/jcli/src/jcli_app/vote/decrypt_shares.rs new file mode 100644 index 0000000000..d4128945de --- /dev/null +++ b/jcli/src/jcli_app/vote/decrypt_shares.rs @@ -0,0 +1,55 @@ +use super::Error; +use crate::jcli_app::utils::{io, OutputFormat}; +use std::path::PathBuf; +use structopt::StructOpt; + +pub struct TallyDecryptWithAllShares { + /// The path to hex-encoded encrypted tally state. If this parameter is not + /// specified, the encrypted tally state will be read from the standard + /// input. + #[structopt(long = "tally")] + encrypted_tally: Option, + #[structopt(long = "threshold", default = 3)] + threshold: usize, + #[strcturopt(long = "maxvotes")] + max_votes: u64, + #[structopt(long = "table_size")] + table_size: usize, + /// The path to encoded necessare shares. If this parameter is not + /// specified, the shares will be read from the standard input. + #[structopt(long = "shares")] + shares: Option, + #[structopt(flatten)] + output_format: OutputFormat, +} + +#[derive(Serialize)] +struct Output { + result: Vec>, +} + +impl TallyDecryptWithAllShares { + pub fn exec(&self) -> Result<(), Error> { + let encrypted_tally_hex = io::read_line(&self.encrypted_tally)?; + let encrypted_tally_bytes = hex::decode(encrypted_tally_hex)?; + let encrypted_tally = + Tally::from_bytes(&encrypted_tally_bytes).ok_or(Error::EncryptedTallyRead)?; + let mut shares_file = io::open_file_read(&self.shares)?; + let shares: Vec = (0..self.threshold) + .map(|_| { + let mut buff = String::new(); + &shares_file.read_line(&mut buff); + chain_vote::TallyDecryptShare::from_bytes(&hex::decode(buff)?) + }) + .collect(); + let state = encrypted_tally.state(); + let result = chain_vote::result(self.max_votes, self.table_size, &state, &shares); + let output = self + .output_format + .format_json(serde_json::to_value(Output { + result: result.votes, + })?)?; + println!("{}", output); + Ok(()) + } +} diff --git a/jcli/src/jcli_app/vote/decryption_share.rs b/jcli/src/jcli_app/vote/decryption_tally.rs similarity index 96% rename from jcli/src/jcli_app/vote/decryption_share.rs rename to jcli/src/jcli_app/vote/decryption_tally.rs index 93e2f381ef..d35be61df3 100644 --- a/jcli/src/jcli_app/vote/decryption_share.rs +++ b/jcli/src/jcli_app/vote/decryption_tally.rs @@ -9,7 +9,7 @@ use structopt::StructOpt; /// The outputs are provided as hex-encoded byte sequences. #[derive(StructOpt)] #[structopt(rename_all = "kebab-case")] -pub struct TallyDecryptionShare { +pub struct TallyGenrateDecryptionShare { /// The path to hex-encoded encrypted tally state. If this parameter is not /// specified, the encrypted tally state will be read from the standard /// input. @@ -28,7 +28,7 @@ struct Output { share: String, } -impl TallyDecryptionShare { +impl TallyGenrateDecryptionShare { pub fn exec(&self) -> Result<(), Error> { let encrypted_tally_hex = io::read_line(&self.encrypted_tally)?; let encrypted_tally_bytes = hex::decode(encrypted_tally_hex)?; @@ -43,14 +43,12 @@ impl TallyDecryptionShare { }; let (state, share) = encrypted_tally.finish(&decryption_key); - let output = self .output_format .format_json(serde_json::to_value(Output { state: hex::encode(state.to_bytes()), share: hex::encode(share.to_bytes()), })?)?; - println!("{}", output); Ok(()) diff --git a/jcli/src/jcli_app/vote/mod.rs b/jcli/src/jcli_app/vote/mod.rs index 84746b396f..6be9556612 100644 --- a/jcli/src/jcli_app/vote/mod.rs +++ b/jcli/src/jcli_app/vote/mod.rs @@ -1,7 +1,8 @@ use crate::jcli_app::utils::output_file::{self, OutputFile}; mod committee; mod common_reference_string; -mod decryption_share; +mod decrypt_shares; +mod decryption_tally; mod encrypting_vote_key; use structopt::StructOpt; @@ -52,7 +53,7 @@ pub enum Vote { /// Build an encryption vote key CRS(common_reference_string::CRS), /// Create decryption share for private voting tally. - TallyDecryptionShare(decryption_share::TallyDecryptionShare), + TallyDecryptionShare(decryption_tally::TallyGenrateDecryptionShare), } impl Vote {