Skip to content

Commit 77c5285

Browse files
committed
Add aggregate verification key to certificate
* Compute aggregate verification key with multisignature * Cleanup code before implementing real stores
1 parent d7cda87 commit 77c5285

File tree

5 files changed

+79
-72
lines changed

5 files changed

+79
-72
lines changed

mithril-aggregator/src/http_server.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use hex::ToHex;
2-
use mithril_common::crypto_helper::{key_decode_hex, ProtocolPartyId};
1+
use mithril_common::crypto_helper::{key_decode_hex, ProtocolLotteryIndex, ProtocolPartyId};
32
use mithril_common::entities;
43
use mithril_common::fake_data;
54
use serde_json::Value::Null;
@@ -200,9 +199,8 @@ mod handlers {
200199
let beacon_store = beacon_store.read().await;
201200
match beacon_store.get_current_beacon().await {
202201
Ok(Some(beacon)) => {
203-
let message = fake_data::digest(&beacon);
204202
let multi_signer = multi_signer.read().await;
205-
match multi_signer.get_multi_signature(&message.encode_hex::<String>()) {
203+
match multi_signer.get_multi_signature() {
206204
Ok(None) => {
207205
let mut certificate_pending = fake_data::certificate_pending();
208206
certificate_pending.beacon = beacon.clone();
@@ -285,9 +283,8 @@ mod handlers {
285283
let beacon_store = beacon_store.read().await;
286284
match beacon_store.get_current_beacon().await {
287285
Ok(Some(beacon)) => {
288-
let message = certificate_hash.clone();
289286
let previous_hash = "".to_string();
290-
match multi_signer.create_certificate(message, beacon, previous_hash) {
287+
match multi_signer.create_certificate(beacon, previous_hash) {
291288
Ok(Some(certificate)) => Ok(warp::reply::with_status(
292289
warp::reply::json(&certificate),
293290
StatusCode::OK,
@@ -475,9 +472,9 @@ mod handlers {
475472
match key_decode_hex(&signature.signature) {
476473
Ok(single_signature) => {
477474
match multi_signer.register_single_signature(
478-
signature.party_id as multi_signer::ProtocolPartyId,
475+
signature.party_id as ProtocolPartyId,
479476
&single_signature,
480-
signature.index as multi_signer::ProtocolLotteryIndex,
477+
signature.index as ProtocolLotteryIndex,
481478
) {
482479
Err(multi_signer::ProtocolError::ExistingSingleSignature(_)) => {
483480
return Ok(warp::reply::with_status(
@@ -562,7 +559,7 @@ mod tests {
562559
.return_once(|| Ok(fake_signers_with_stakes));
563560
mock_multi_signer
564561
.expect_get_multi_signature()
565-
.return_once(|_| Ok(None));
562+
.return_once(|| Ok(None));
566563
let mut dependency_manager = setup_dependency_manager();
567564

568565
dependency_manager
@@ -667,7 +664,7 @@ mod tests {
667664
.return_once(|| Err(ProtocolError::Codec("an error occurred".to_string())));
668665
mock_multi_signer
669666
.expect_get_multi_signature()
670-
.return_once(|_| Ok(None));
667+
.return_once(|| Ok(None));
671668
let mut dependency_manager = setup_dependency_manager();
672669
dependency_manager
673670
.with_multi_signer(Arc::new(RwLock::new(mock_multi_signer)))
@@ -703,7 +700,7 @@ mod tests {
703700
.return_once(|| None);
704701
mock_multi_signer
705702
.expect_get_multi_signature()
706-
.return_once(|_| Ok(None));
703+
.return_once(|| Ok(None));
707704
let mut dependency_manager = setup_dependency_manager();
708705
dependency_manager
709706
.with_multi_signer(Arc::new(RwLock::new(mock_multi_signer)))
@@ -735,9 +732,7 @@ mod tests {
735732
let mut mock_multi_signer = MockMultiSigner::new();
736733
mock_multi_signer
737734
.expect_create_certificate()
738-
.return_once(move |_, _, _| {
739-
Ok(Some(fake_data::certificate("cert-hash-123".to_string())))
740-
});
735+
.return_once(move |_, _| Ok(Some(fake_data::certificate("cert-hash-123".to_string()))));
741736
let mut dependency_manager = setup_dependency_manager();
742737
dependency_manager
743738
.with_multi_signer(Arc::new(RwLock::new(mock_multi_signer)))
@@ -770,7 +765,7 @@ mod tests {
770765
let mut mock_multi_signer = MockMultiSigner::new();
771766
mock_multi_signer
772767
.expect_create_certificate()
773-
.return_once(move |_, _, _| Ok(None));
768+
.return_once(move |_, _| Ok(None));
774769
let mut dependency_manager = setup_dependency_manager();
775770
dependency_manager
776771
.with_multi_signer(Arc::new(RwLock::new(mock_multi_signer)))
@@ -803,7 +798,7 @@ mod tests {
803798
let mut mock_multi_signer = MockMultiSigner::new();
804799
mock_multi_signer
805800
.expect_create_certificate()
806-
.return_once(move |_, _, _| Err(ProtocolError::Codec("an error occurred".to_string())));
801+
.return_once(move |_, _| Err(ProtocolError::Codec("an error occurred".to_string())));
807802
let mut dependency_manager = setup_dependency_manager();
808803
dependency_manager
809804
.with_multi_signer(Arc::new(RwLock::new(mock_multi_signer)))

mithril-aggregator/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ mod tools;
1111

1212
pub use crate::entities::Config;
1313
pub use crate::http_server::Server;
14-
pub use crate::multi_signer::{
15-
key_decode_hex, MultiSigner, MultiSignerImpl, ProtocolError, ProtocolParameters,
16-
ProtocolPartyId, ProtocolSignerVerificationKey, ProtocolStake, ProtocolStakeDistribution,
17-
};
14+
pub use crate::multi_signer::{MultiSigner, MultiSignerImpl, ProtocolError};
1815
pub use crate::snapshot_stores::{RemoteSnapshotStore, SnapshotStore};
1916
pub use beacon_store::{BeaconStoreError, MemoryBeaconStore};
2017
pub use dependency::DependencyManager;

mithril-aggregator/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ use clap::Parser;
55
use config::{Map, Source, Value, ValueKind};
66
use mithril_aggregator::{
77
AggregatorRuntime, Config, DependencyManager, MemoryBeaconStore, MultiSigner, MultiSignerImpl,
8-
ProtocolStakeDistribution, Server,
8+
Server,
99
};
10+
use mithril_common::crypto_helper::ProtocolStakeDistribution;
1011
use mithril_common::fake_data;
1112
use slog::{Drain, Level, Logger};
1213
use slog_scope::debug;

mithril-aggregator/src/multi_signer.rs

Lines changed: 64 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ use slog_scope::{debug, warn};
44
use std::collections::HashMap;
55
use thiserror::Error;
66

7-
// TODO: remove pub
8-
pub use mithril_common::crypto_helper::{
9-
key_decode_hex, key_encode_hex, Bytes, ProtocolClerk, ProtocolKeyRegistration,
10-
ProtocolLotteryIndex, ProtocolMultiSignature, ProtocolParameters, ProtocolPartyId,
11-
ProtocolSignerVerificationKey, ProtocolSingleSignature, ProtocolStake,
7+
use mithril_common::crypto_helper::{
8+
key_encode_hex, Bytes, ProtocolAggregateVerificationKey, ProtocolClerk,
9+
ProtocolKeyRegistration, ProtocolLotteryIndex, ProtocolMultiSignature, ProtocolParameters,
10+
ProtocolPartyId, ProtocolSignerVerificationKey, ProtocolSingleSignature,
1211
ProtocolStakeDistribution,
1312
};
1413
use mithril_common::entities;
@@ -35,6 +34,9 @@ pub enum ProtocolError {
3534

3635
#[error("no protocol parameters available")]
3736
UnavailableProtocolParameters(),
37+
38+
#[error("no clerk available")]
39+
UnavailableClerk(),
3840
}
3941

4042
/// MultiSigner is the cryptographic engine in charge of producing multi signatures from individual signatures
@@ -89,18 +91,14 @@ pub trait MultiSigner: Sync + Send {
8991
) -> Result<(), ProtocolError>;
9092

9193
/// Retrieves a multi signature from a message
92-
fn get_multi_signature(
93-
&self,
94-
message: &str,
95-
) -> Result<Option<ProtocolMultiSignature>, ProtocolError>;
94+
fn get_multi_signature(&self) -> Result<Option<ProtocolMultiSignature>, ProtocolError>;
9695

9796
/// Creates a multi signature from single signatures
9897
fn create_multi_signature(&mut self) -> Result<Option<ProtocolMultiSignature>, ProtocolError>;
9998

10099
/// Creates a certificate from a multi signatures
101100
fn create_certificate(
102101
&self,
103-
message: String,
104102
beacon: entities::Beacon,
105103
previous_hash: String,
106104
) -> Result<Option<entities::Certificate>, ProtocolError>;
@@ -124,8 +122,11 @@ pub struct MultiSignerImpl {
124122
single_signatures:
125123
HashMap<ProtocolPartyId, HashMap<ProtocolLotteryIndex, ProtocolSingleSignature>>,
126124

127-
/// Recorded multi signatures by message signed
128-
multi_signatures: HashMap<String, String>,
125+
/// Created multi signature for message signed
126+
multi_signature: Option<ProtocolMultiSignature>,
127+
128+
/// Created aggregate verification key
129+
avk: Option<ProtocolAggregateVerificationKey>,
129130
}
130131

131132
impl Default for MultiSignerImpl {
@@ -144,24 +145,35 @@ impl MultiSignerImpl {
144145
stakes: Vec::new(),
145146
signers: HashMap::new(),
146147
single_signatures: HashMap::new(),
147-
multi_signatures: HashMap::new(),
148+
multi_signature: None,
149+
avk: None,
148150
}
149151
}
150152

151153
/// Creates a clerk
152154
// TODO: The clerk should be a field of the MultiSignerImpl struct, but this is not possible now as the Clerk uses an unsafe 'Rc'
153-
pub fn clerk(&self) -> ProtocolClerk {
155+
pub fn create_clerk(&self) -> Option<ProtocolClerk> {
154156
let stakes = self.get_stake_distribution();
155157
let mut key_registration = ProtocolKeyRegistration::init(&stakes);
158+
let mut total_signers = 0;
156159
stakes.iter().for_each(|(party_id, _stake)| {
157160
if let Some(verification_key) = self.get_signer(*party_id).unwrap() {
158161
key_registration
159162
.register(*party_id, verification_key)
160163
.unwrap();
164+
total_signers += 1;
161165
}
162166
});
163-
let closed_registration = key_registration.close();
164-
ProtocolClerk::from_registration(self.protocol_parameters.unwrap(), closed_registration)
167+
match total_signers {
168+
0 => None,
169+
_ => {
170+
let closed_registration = key_registration.close();
171+
Some(ProtocolClerk::from_registration(
172+
self.protocol_parameters?,
173+
closed_registration,
174+
))
175+
}
176+
}
165177
}
166178
}
167179

@@ -174,6 +186,8 @@ impl MultiSigner for MultiSignerImpl {
174186
/// Update current message
175187
fn update_current_message(&mut self, message: Bytes) -> Result<(), ProtocolError> {
176188
self.current_message = Some(message);
189+
self.multi_signature = None;
190+
self.single_signatures.drain();
177191
Ok(())
178192
}
179193

@@ -248,7 +262,6 @@ impl MultiSigner for MultiSignerImpl {
248262
}
249263

250264
/// Registers a single signature
251-
// TODO: Maybe the clerk can be replaced here by a verifier in the crypto library (cf https://github.com/input-output-hk/mithril/issues/162)
252265
fn register_single_signature(
253266
&mut self,
254267
party_id: ProtocolPartyId,
@@ -263,9 +276,17 @@ impl MultiSigner for MultiSignerImpl {
263276
let message = &self
264277
.get_current_message()
265278
.ok_or_else(ProtocolError::UnavailableMessage)?;
266-
let clerk = self.clerk();
267-
let avk = clerk.compute_avk();
268-
match signature.verify(&self.protocol_parameters.unwrap(), &avk, message) {
279+
match signature.verify(
280+
&self
281+
.protocol_parameters
282+
.ok_or_else(ProtocolError::UnavailableProtocolParameters)?,
283+
&self
284+
.create_clerk()
285+
.as_ref()
286+
.ok_or_else(ProtocolError::UnavailableClerk)?
287+
.compute_avk(),
288+
message,
289+
) {
269290
Ok(_) => {
270291
// Register single signature
271292
self.single_signatures
@@ -292,19 +313,9 @@ impl MultiSigner for MultiSignerImpl {
292313
}
293314

294315
/// Retrieves a multi signature from a message
295-
fn get_multi_signature(
296-
&self,
297-
message: &str,
298-
) -> Result<Option<ProtocolMultiSignature>, ProtocolError> {
299-
debug!("Get multi signature for message {}", message);
300-
match self.multi_signatures.get(message) {
301-
Some(multi_signature) => {
302-
let multi_signature: ProtocolMultiSignature =
303-
key_decode_hex(multi_signature).map_err(ProtocolError::Codec)?;
304-
Ok(Some(multi_signature))
305-
}
306-
None => Ok(None),
307-
}
316+
fn get_multi_signature(&self) -> Result<Option<ProtocolMultiSignature>, ProtocolError> {
317+
debug!("Get multi signature");
318+
Ok(self.multi_signature.to_owned())
308319
}
309320

310321
/// Creates a multi signature from single signatures
@@ -329,12 +340,13 @@ impl MultiSigner for MultiSignerImpl {
329340
return Ok(None);
330341
}
331342

332-
match self.clerk().aggregate(&signatures, message) {
343+
let clerk = self
344+
.create_clerk()
345+
.ok_or_else(ProtocolError::UnavailableClerk)?;
346+
match clerk.aggregate(&signatures, message) {
333347
Ok(multi_signature) => {
334-
self.multi_signatures.insert(
335-
message.encode_hex::<String>(),
336-
key_encode_hex(&multi_signature).map_err(ProtocolError::Codec)?,
337-
);
348+
self.avk = Some(clerk.compute_avk());
349+
self.multi_signature = Some(multi_signature.clone());
338350
self.single_signatures.drain();
339351
Ok(Some(multi_signature))
340352
}
@@ -346,35 +358,38 @@ impl MultiSigner for MultiSignerImpl {
346358
// TODO: Clarify what started/completed date represents
347359
fn create_certificate(
348360
&self,
349-
message: String,
350361
beacon: entities::Beacon,
351362
previous_hash: String,
352363
) -> Result<Option<entities::Certificate>, ProtocolError> {
353364
debug!("Create certificate");
354365

355-
match self.get_multi_signature(&message)? {
366+
match self.get_multi_signature()? {
356367
Some(multi_signature) => {
357368
let protocol_parameters = self
358369
.get_protocol_parameters()
359370
.ok_or_else(ProtocolError::UnavailableProtocolParameters)?
360371
.into();
361-
let digest = message.clone();
362-
let certificate_hash = message;
372+
let digest = self
373+
.get_current_message()
374+
.ok_or_else(ProtocolError::UnavailableMessage)?
375+
.encode_hex::<String>();
363376
let previous_hash = previous_hash;
364377
let started_at = format!("{:?}", Utc::now());
365378
let completed_at = started_at.clone();
366379
let signers = self.get_signers()?;
380+
let aggregate_verification_key =
381+
key_encode_hex(&self.avk.as_ref().unwrap()).map_err(ProtocolError::Codec)?;
367382
let multi_signature =
368383
key_encode_hex(&multi_signature).map_err(ProtocolError::Codec)?;
369384
Ok(Some(entities::Certificate::new(
370-
certificate_hash,
371385
previous_hash,
372386
beacon,
373387
protocol_parameters,
374388
digest,
375389
started_at,
376390
completed_at,
377391
signers,
392+
aggregate_verification_key,
378393
multi_signature,
379394
)))
380395
}
@@ -488,7 +503,6 @@ mod tests {
488503
let mut multi_signer = MultiSignerImpl::new();
489504

490505
let message = setup_message();
491-
let message_hex = message.clone().encode_hex::<String>();
492506
multi_signer
493507
.update_current_message(message.clone())
494508
.expect("update current message failed");
@@ -531,11 +545,11 @@ mod tests {
531545
.create_multi_signature()
532546
.expect("create multi sgnature should not fail");
533547
assert!(multi_signer
534-
.get_multi_signature(&message_hex)
548+
.get_multi_signature()
535549
.expect("get multi signature should not fail")
536550
.is_none());
537551
assert!(multi_signer
538-
.create_certificate(message_hex.clone(), beacon.clone(), previous_hash.clone())
552+
.create_certificate(beacon.clone(), previous_hash.clone())
539553
.expect("create_certificate should not fail")
540554
.is_none());
541555
signatures[0..quorum_split]
@@ -549,11 +563,11 @@ mod tests {
549563
.create_multi_signature()
550564
.expect("create multi sgnature should not fail");
551565
assert!(multi_signer
552-
.get_multi_signature(&message_hex)
566+
.get_multi_signature()
553567
.expect("get multi signature should not fail")
554568
.is_none());
555569
assert!(multi_signer
556-
.create_certificate(message_hex.clone(), beacon.clone(), previous_hash.clone())
570+
.create_certificate(beacon.clone(), previous_hash.clone())
557571
.expect("create_certificate should not fail")
558572
.is_none());
559573
signatures[quorum_split..]
@@ -567,11 +581,11 @@ mod tests {
567581
.create_multi_signature()
568582
.expect("create multi sgnature should not fail");
569583
assert!(multi_signer
570-
.get_multi_signature(&message_hex)
584+
.get_multi_signature()
571585
.expect("get multi signature should not fail")
572586
.is_some());
573587
assert!(multi_signer
574-
.create_certificate(message_hex.clone(), beacon.clone(), previous_hash.clone())
588+
.create_certificate(beacon.clone(), previous_hash.clone())
575589
.expect("create_certificate should not fail")
576590
.is_some());
577591
}

0 commit comments

Comments
 (0)