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
use SdaClient;
use crypto::*;
use errors::SdaClientResult;
use sda_protocol::*;
pub trait Clerking {
fn clerk_once(&self) -> SdaClientResult<bool>;
fn run_chores(&self, max_iterations: isize) -> SdaClientResult<()>;
}
impl Clerking for SdaClient {
fn clerk_once(&self) -> SdaClientResult<bool> {
let job = self.service.get_clerking_job(&self.agent, &self.agent.id)?;
match job {
None => {
Ok(false)
},
Some(job) => {
let result = self.process_clerking_job(&job)?;
self.service.create_clerking_result(&self.agent, &result)?;
Ok(true)
}
}
}
fn run_chores(&self, max_iterations: isize) -> SdaClientResult<()> {
if max_iterations < 0 {
loop {
if !self.clerk_once()? {
break
}
}
} else {
for _ in 0..max_iterations {
if !self.clerk_once()? {
break
}
}
}
return Ok(())
}
}
impl SdaClient {
fn process_clerking_job(&self, job: &ClerkingJob) -> SdaClientResult<ClerkingResult> {
let aggregation = self.service.get_aggregation(&self.agent, &job.aggregation)?
.ok_or("Unknown aggregation")?;
let committee = self.service.get_committee(&self.agent, &job.aggregation)?
.ok_or("Unknown committee")?;
let own_signed_encryption_key_id = committee.clerks_and_keys.iter().find(|&&(id,_)| id == self.agent.id)
.ok_or("Could not find own encryption key in keyset")?.1;
let share_decryptor = self.crypto.new_share_decryptor(&own_signed_encryption_key_id, &aggregation.committee_encryption_scheme)?;
let partially_combined_shares = job.encryptions.iter()
.map(|encryption| Ok(share_decryptor.decrypt(encryption)?))
.collect::<SdaClientResult<Vec<Vec<Share>>>>()?;
let share_combiner = self.crypto.new_share_combiner(&aggregation.committee_sharing_scheme)?;
let fully_combined_shares: Vec<Share> = share_combiner.combine(&partially_combined_shares)?;
let recipient_id = &aggregation.recipient;
let recipient = self.service.get_agent(&self.agent, recipient_id)?
.ok_or("Unknown recipient")?;
let recipient_signed_encryption_key = self.service.get_encryption_key(&self.agent, &aggregation.recipient_key)?
.ok_or("Unknown recipient encryption key")?;
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 share_encryptor = self.crypto.new_share_encryptor(&recipient_encryption_key, &aggregation.recipient_encryption_scheme)?;
let recipient_encryption: Encryption = share_encryptor.encrypt(&fully_combined_shares)?;
Ok(ClerkingResult {
job: job.id.clone(),
clerk: job.clerk,
encryption: recipient_encryption,
})
}
}