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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use SdaClient;
use crypto::*;
use errors::SdaClientResult;
use sda_protocol::*;
pub struct ParticipantInput(pub Vec<Secret>);
pub trait Participating {
fn new_participation(&self, input: &ParticipantInput, aggregation: &AggregationId) -> SdaClientResult<Participation>;
fn upload_participation(&self, input: &Participation) -> SdaClientResult<()>;
fn participate(&self, input: Vec<i64>, aggregation: &AggregationId) -> SdaClientResult<()>;
}
impl Participating for SdaClient {
fn participate(&self, input: Vec<i64>, aggregation: &AggregationId) -> SdaClientResult<()> {
let input = ParticipantInput(input);
let participation = self.new_participation(&input, &aggregation)?;
self.upload_participation(&participation)
}
fn new_participation(&self, input: &ParticipantInput, aggregation_id: &AggregationId) -> SdaClientResult<Participation> {
let secrets = &input.0;
let aggregation = self.service.get_aggregation(&self.agent, aggregation_id)?
.ok_or("Could not find aggregation")?;
if secrets.len() != aggregation.vector_dimension {
Err("The input length does not match the aggregation.")?
}
let committee: Committee = self.service.get_committee(&self.agent, aggregation_id)?
.ok_or("Could not find committee")?;
let mut secret_masker = self.crypto.new_secret_masker(&aggregation.masking_scheme)?;
let (recipient_mask, committee_masked_secrets) = secret_masker.mask(secrets);
let recipient_encryption: Option<Encryption> = if recipient_mask.len() == 0 {
None
} else {
let recipient_id = &aggregation.recipient;
let recipient_signed_encryption_key = self.service.get_encryption_key(&self.agent, &aggregation.recipient_key)?
.ok_or("Unknown recipient encryption key")?;
let recipient = self.service.get_agent(&self.agent, recipient_id)?
.ok_or("Unknown recipient")?;
if !recipient.signature_is_valid(&recipient_signed_encryption_key)? {
Err("Signature verification failed for recipient key")?
}
let recipient_encryption_key = recipient_signed_encryption_key.body.body;
let mask_encryptor = self.crypto.new_share_encryptor(&recipient_encryption_key, &aggregation.recipient_encryption_scheme)?;
Some(mask_encryptor.encrypt(&*recipient_mask)?)
};
let mut share_generator = self.crypto.new_share_generator(&aggregation.committee_sharing_scheme)?;
let committee_shares_per_clerk: Vec<Vec<Share>> = share_generator.generate(&committee_masked_secrets)?;
let mut clerk_encryptions: Vec<(AgentId, Encryption)> = vec![];
for clerk_index in 0..committee_shares_per_clerk.len() {
let clerk_shares = &committee_shares_per_clerk[clerk_index];
let clerk_id = &committee.clerks_and_keys[clerk_index].0;
let clerk_signed_encryption_key_id = committee.clerks_and_keys[clerk_index].1;
let clerk_signed_encryption_key = self.service.get_encryption_key(&self.agent, &clerk_signed_encryption_key_id)?
.ok_or("Unknown clerk encryption key")?;
let clerk = self.service.get_agent(&self.agent, clerk_id)?
.ok_or("Unknown clerk")?;
if !clerk.signature_is_valid(&clerk_signed_encryption_key)? {
Err("Signature verification failed for clerk key")?
}
let clerk_encryption_key = clerk_signed_encryption_key.body.body;
let share_encryptor = self.crypto.new_share_encryptor(&clerk_encryption_key, &aggregation.committee_encryption_scheme)?;
let clerk_encryption: Encryption = share_encryptor.encrypt(&*clerk_shares)?;
clerk_encryptions.push((clerk_id.clone(), clerk_encryption));
}
let participation_id = ParticipationId::random();
Ok(Participation {
id: participation_id,
participant: self.agent.id.clone(),
aggregation: aggregation.id.clone(),
recipient_encryption: recipient_encryption,
clerk_encryptions: clerk_encryptions,
})
}
fn upload_participation(&self, input: &Participation) -> SdaClientResult<()> {
Ok(self.service.create_participation(&self.agent, input)?)
}
}