1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::vote::VotePlanStatus;
use chain_vote::{
    committee::MemberSecretKey, Crs, ElectionPublicKey, MemberCommunicationKey, MemberPublicKey,
    MemberState, TallyDecryptShare,
};
use rand::thread_rng;
use rand_core::CryptoRng;
use rand_core::RngCore;

pub struct CommitteeMembersManager {
    members: Vec<CommitteeMember>,
    crs: Crs,
}

pub struct CommitteeMember {
    state: MemberState,
}

impl CommitteeMembersManager {
    pub fn new(
        rng: &mut (impl RngCore + CryptoRng),
        crs_seed: &[u8],
        threshold: usize,
        members_no: usize,
    ) -> Self {
        let mut public_keys = Vec::new();
        for _ in 0..members_no {
            let private_key = MemberCommunicationKey::new(rng);
            let public_key = private_key.to_public();
            public_keys.push(public_key);
        }

        let crs = Crs::from_hash(crs_seed);

        let mut members = Vec::new();
        for i in 0..members_no {
            let state = MemberState::new(rng, threshold, &crs, &public_keys, i);
            members.push(CommitteeMember { state })
        }

        Self { members, crs }
    }

    pub fn members(&self) -> &[CommitteeMember] {
        &self.members
    }

    pub fn members_keys(&self) -> Vec<MemberPublicKey> {
        self.members()
            .iter()
            .map(|committee_member| committee_member.public_key())
            .collect()
    }

    pub fn election_pk(&self) -> ElectionPublicKey {
        let keys: Vec<_> = self.members().iter().map(|x| x.public_key()).collect();
        ElectionPublicKey::from_participants(&keys)
    }

    pub fn crs(&self) -> &Crs {
        &self.crs
    }
}

impl CommitteeMember {
    pub fn public_key(&self) -> MemberPublicKey {
        self.state.public_key()
    }

    pub fn secret_key(&self) -> &MemberSecretKey {
        self.state.secret_key()
    }

    pub fn produce_decrypt_shares(
        &self,
        vote_plan_status: &VotePlanStatus,
    ) -> Vec<TallyDecryptShare> {
        vote_plan_status
            .proposals
            .iter()
            .map(|proposal| {
                let encrypted_tally = proposal.tally.private_encrypted().unwrap().clone();
                encrypted_tally.partial_decrypt(&mut thread_rng(), self.secret_key())
            })
            .collect()
    }
}