@@ -4,11 +4,10 @@ use slog_scope::{debug, warn};
44use std:: collections:: HashMap ;
55use 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} ;
1413use 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
131132impl 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