diff --git a/src/sign/Cargo.toml b/src/sign/Cargo.toml index e8db56ab10..b8c4c40c72 100644 --- a/src/sign/Cargo.toml +++ b/src/sign/Cargo.toml @@ -35,6 +35,6 @@ serde_json = "1.0" serde_yaml = "0.8.17" rand = "0.8.3" bech32 = "0.8" -rand_core = { version = "0.5.1", default-features = false } +rand_core = { version = "0.5.1", default-features = false, features = ["getrandom"] } ed25519-dalek = "1.0.1" reqwest = { version = "*", default_features = false, features = [ "blocking","json", "rustls-tls" ] } diff --git a/src/sign/src/main.rs b/src/sign/src/main.rs index 60e6c789f2..27da8081cd 100644 --- a/src/sign/src/main.rs +++ b/src/sign/src/main.rs @@ -10,11 +10,7 @@ use clap::Parser; use color_eyre::Result; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; -use catalyst_voting::{ - crypto::{ed25519::PrivateKey}, - txs::v1::Tx, - vote_protocol::committee::ElectionSecretKey, -}; +use std::convert::TryInto; use ed25519_dalek::*; use std::error::Error; @@ -24,10 +20,9 @@ use crate::fragment::{compose_encrypted_vote_part, generate_vote_fragment}; pub mod fragment; pub mod network; - /// /// Args defines and declares CLI behaviour within the context of clap -/// +/// #[derive(Parser, Debug, Clone)] #[clap(about, version, author)] pub enum Cli { @@ -65,21 +60,22 @@ pub struct CliArgs { choice: u8, } - fn main() -> Result<(), Box> { color_eyre::install()?; let cli = Cli::parse(); + let mut rng = ChaCha20Rng::from_entropy(); match cli { - Cli::V1(args) => v1_exec(args), - Cli::V2(args) => v2_exec(args), + Cli::V1(args) => v1_exec(args, &mut rng), + Cli::V2(args) => v2_exec(args, &mut rng), } } -fn v1_exec(args: CliArgs) -> Result<(), Box> { - let mut rng = ChaCha20Rng::from_seed([0u8; 32]); +/// Number of voting options +const VOTING_OPTIONS: u8 = 2; +fn v1_exec(args: CliArgs, rng: &mut ChaCha20Rng) -> Result<(), Box> { let pk = hex::decode(args.public_key)?; let mut sk = hex::decode(args.private_key)?; @@ -96,7 +92,7 @@ fn v1_exec(args: CliArgs) -> Result<(), Box> { let choice = args.choice; - let vote = chain_vote::Vote::new(2, choice.into())?; + let vote = chain_vote::Vote::new(VOTING_OPTIONS.into(), choice.into())?; // common reference string let crs = chain_vote::Crs::from_hash(&hex::decode(args.vote_plan_id.clone())?); @@ -104,7 +100,7 @@ fn v1_exec(args: CliArgs) -> Result<(), Box> { let ek = ElectionPublicKey::from_bytes(&election_pk) .ok_or("unable to parse election pub key".to_string())?; - let (ciphertexts, proof) = ek.encrypt_and_prove_vote(&mut rng, &crs, vote); + let (ciphertexts, proof) = ek.encrypt_and_prove_vote(rng, &crs, vote); let (proof, encrypted_vote) = compose_encrypted_vote_part(ciphertexts.clone(), proof)?; let fragment_bytes = generate_vote_fragment( @@ -123,50 +119,46 @@ fn v1_exec(args: CliArgs) -> Result<(), Box> { Ok(()) } -fn v2_exec(args: CliArgs) -> Result<(), Box> { - let mut rng = ChaCha20Rng::from_seed([0u8; 32]); - - // let pk = hex::decode(args.public_key)?; - let mut sk = hex::decode(args.private_key)?; +fn v2_exec(args: CliArgs, rng: &mut ChaCha20Rng) -> Result<(), Box> { + let sk_bytes = hex::decode(args.private_key)?; // Election pub key published as a Bech32_encoded address // which consists of 3 parts: A Human-Readable Part (HRP) + Separator + Data: let (_hrp, data, _variant) = bech32::decode(&args.election_pub_key).map_err(Bech32Error::from)?; - let election_pk = Vec::::from_base32(&data).map_err(Bech32Error::from)?; - - - - // join sk+pk together, api requirement - sk.extend(pk.clone()); - let keypair: Keypair = Keypair::from_bytes(&sk)?; - + let election_pk_bytes = Vec::::from_base32(&data).map_err(Bech32Error::from)?; + + let private_key = catalyst_voting::crypto::ed25519::PrivateKey::from_bytes( + &sk_bytes + .try_into() + .map_err(|_| "private key invalid length")?, + ); + let election_public_key = + catalyst_voting::vote_protocol::committee::ElectionPublicKey::from_bytes( + &election_pk_bytes + .try_into() + .map_err(|_| "election public key invalid length")?, + )?; + + let vote_plan_id = hex::decode(args.vote_plan_id.clone())? + .try_into() + .map_err(|_| "vote plan id invalid length")?; + let proposal_index = args.proposal; let choice = args.choice; - let vote = chain_vote::Vote::new(2, choice.into())?; - // common reference string - let crs = chain_vote::Crs::from_hash(&hex::decode(args.vote_plan_id.clone())?); - - // parse ek key - let ek = ElectionPublicKey::from_bytes(&election_pk) - .ok_or("unable to parse election pub key".to_string())?; - - let (ciphertexts, proof) = ek.encrypt_and_prove_vote(&mut rng, &crs, vote); - let (proof, encrypted_vote) = compose_encrypted_vote_part(ciphertexts.clone(), proof)?; - - let fragment_bytes = generate_vote_fragment( - keypair, - encrypted_vote, - proof, - args.proposal, - &hex::decode(args.vote_plan_id)?, - args.epoch, - args.slot, + let tx = catalyst_voting::txs::v1::Tx::new_private( + vote_plan_id, + proposal_index, + VOTING_OPTIONS, + choice, + &election_public_key, + &private_key, + rng, )?; // fragment in hex: output consumed as input to another program - println!("{:?}", hex::encode(fragment_bytes.clone())); + println!("{:?}", hex::encode(tx.to_bytes())); Ok(()) }