@@ -7,39 +7,17 @@ use crate::bls::{
77 bls_id_from_u32, bls_verify, evaluate_polynomial, lagrange_interpolation, PublicKey , SecretKey ,
88} ;
99
10- pub enum ProveResult {
11- Ok ,
12- SlashableError ,
13- UnslashableError ,
14- }
15-
1610#[ derive( Debug ) ]
1711pub enum VerificationErrors {
18- InvalidCommitment ( String ) ,
19- InvalidSharedSecret ( String ) ,
20- InvalidSignature ( String ) ,
21- InvalidVerificationVector ( String ) ,
22- InvalidCommitmentHash ( String ) ,
23- InvalidSignatureHash ( String ) ,
12+ SlashableError ( String ) ,
13+ UnslashableError ( String ) ,
2414}
2515
2616impl std:: fmt:: Display for VerificationErrors {
2717 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2818 match self {
29- VerificationErrors :: InvalidCommitment ( msg) => write ! ( f, "Invalid commitment: {}" , msg) ,
30- VerificationErrors :: InvalidSharedSecret ( msg) => {
31- write ! ( f, "Invalid shared secret: {}" , msg)
32- }
33- VerificationErrors :: InvalidSignature ( msg) => write ! ( f, "Invalid signature: {}" , msg) ,
34- VerificationErrors :: InvalidVerificationVector ( msg) => {
35- write ! ( f, "Invalid verification vector: {}" , msg)
36- }
37- VerificationErrors :: InvalidCommitmentHash ( msg) => {
38- write ! ( f, "Invalid commitment hash: {}" , msg)
39- }
40- VerificationErrors :: InvalidSignatureHash ( msg) => {
41- write ! ( f, "Invalid signature hash: {}" , msg)
42- }
19+ VerificationErrors :: SlashableError ( e) => write ! ( f, "{}" , e) ,
20+ VerificationErrors :: UnslashableError ( e) => write ! ( f, "{}" , e) ,
4321 }
4422 }
4523}
@@ -89,7 +67,7 @@ pub fn verify_seed_exchange_commitment(
8967 verification_hashes : & dvt_abi:: AbiVerificationHashes ,
9068 seed_exchange : & dvt_abi:: AbiSeedExchangeCommitment ,
9169 initial_commitment : & dvt_abi:: AbiInitialCommitment ,
92- ) -> ProveResult {
70+ ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
9371 let commitment = & seed_exchange. commitment ;
9472 let shared_secret = & seed_exchange. shared_secret ;
9573
@@ -102,26 +80,37 @@ pub fn verify_seed_exchange_commitment(
10280 . unwrap ( ) ,
10381 & commitment. hash ,
10482 ) {
105- print ! ( "Failed to verify seed exchange commitment\n " ) ;
106- return ProveResult :: UnslashableError ;
83+ // Return unslashable error
84+ return Err ( Box :: new ( VerificationErrors :: UnslashableError (
85+ String :: from ( format ! (
86+ "Invalid field seeds_exchange_commitment.commitment.signature {}\n " ,
87+ hex:: encode( commitment. signature)
88+ ) ) ,
89+ ) ) ) ;
10790 }
10891
109- if SecretKey :: from_bytes ( & shared_secret. secret ) . is_err ( ) {
110- print ! ( "Invalid field seeds_exchange_commitment.shared_secret.secret\n " ) ;
111- return ProveResult :: SlashableError ;
92+ let sk = SecretKey :: from_bytes ( & shared_secret. secret ) ;
93+ if sk. is_err ( ) {
94+ return Err ( Box :: new ( VerificationErrors :: SlashableError ( String :: from (
95+ format ! (
96+ "Invalid field seeds_exchange_commitment.shared_secret.secret: {} \n " ,
97+ sk. unwrap_err( )
98+ ) ,
99+ ) ) ) ) ;
112100 }
113101
114- let sk = SecretKey :: from_bytes ( & shared_secret . secret ) . unwrap ( ) ;
102+ let sk = sk . unwrap ( ) ;
115103
116104 let computed_commitment_hash = compute_seed_exchange_hash ( seed_exchange) ;
117105
118106 if computed_commitment_hash. to_vec ( ) != seed_exchange. commitment . hash {
119- print ! (
120- "Invalid field seeds_exchange_commitment.commitment.hash. Expected: {:?}, got hash: {:?}\n " ,
121- hex:: encode( seed_exchange. commitment. hash) ,
122- hex:: encode( computed_commitment_hash. to_vec( ) )
123- ) ;
124- return ProveResult :: SlashableError ;
107+ return Err ( Box :: new ( VerificationErrors :: SlashableError (
108+ String :: from ( format ! (
109+ "Invalid field seeds_exchange_commitment.commitment.hash. Expected: {:?}, got hash: {:?}\n " ,
110+ hex:: encode( seed_exchange. commitment. hash) ,
111+ hex:: encode( computed_commitment_hash. to_vec( ) )
112+ ) ) ,
113+ ) ) ) ;
125114 }
126115
127116 let dest_id = get_index_in_commitments (
@@ -130,8 +119,12 @@ pub fn verify_seed_exchange_commitment(
130119 ) ;
131120
132121 if dest_id. is_err ( ) {
133- print ! ( "Invalid field seeds_exchange_commitment.shared_secret.dst_id\n " ) ;
134- return ProveResult :: SlashableError ;
122+ return Err ( Box :: new ( VerificationErrors :: SlashableError ( String :: from (
123+ format ! (
124+ "Invalid field seeds_exchange_commitment.shared_secret.dst_id: {} \n " ,
125+ dest_id. unwrap_err( )
126+ ) ,
127+ ) ) ) ) ;
135128 }
136129
137130 let unwraped = dest_id. unwrap ( ) + 1 ;
@@ -147,24 +140,26 @@ pub fn verify_seed_exchange_commitment(
147140 let id = Scalar :: from_bytes ( & le_bytes) . unwrap ( ) ;
148141
149142 if id != test_id {
150- print ! ( "Invalid field seeds_exchange_commitment.shared_secret.dst_id\n " ) ;
151- return ProveResult :: SlashableError ;
143+ return Err ( Box :: new ( VerificationErrors :: SlashableError ( String :: from (
144+ "Invalid field seeds_exchange_commitment.shared_secret.dst_id\n " ,
145+ ) ) ) ) ;
152146 }
153147 let eval_result = evaluate_polynomial ( cfst, id) ;
154148
155149 if !sk. to_public_key ( ) . eq ( & eval_result) {
156- print ! (
157- "Bad secret field : {:?}, got pk: {:?}\n " ,
158- PublicKey :: from_g1( & eval_result) ,
159- sk. to_public_key( )
160- ) ;
161- return ProveResult :: SlashableError ;
150+ return Err ( Box :: new ( VerificationErrors :: SlashableError ( String :: from (
151+ format ! (
152+ "Bad secret field : Expected secret with public key: {:?}, got public key: {:?}\n " ,
153+ PublicKey :: from_g1( & eval_result) ,
154+ sk. to_public_key( )
155+ ) ,
156+ ) ) ) ) ;
162157 }
163158
164- ProveResult :: Ok
159+ Ok ( ( ) )
165160}
166161
167- pub fn verify_initial_commitment ( commitment : & dvt_abi:: AbiInitialCommitment ) -> ProveResult {
162+ pub fn verify_initial_commitment_hash ( commitment : & dvt_abi:: AbiInitialCommitment ) -> bool {
168163 let mut hasher = Sha256 :: new ( ) ;
169164
170165 hasher. update ( [ commitment. settings . n ] ) ;
@@ -173,12 +168,8 @@ pub fn verify_initial_commitment(commitment: &dvt_abi::AbiInitialCommitment) ->
173168 for pubkey in & commitment. verification_vector . pubkeys {
174169 hasher. update ( & pubkey) ;
175170 }
176-
177- if hasher. finalize ( ) . to_vec ( ) != commitment. hash {
178- return ProveResult :: UnslashableError ;
179- }
180-
181- ProveResult :: Ok
171+ let computed_hash = hasher. finalize ( ) . to_vec ( ) ;
172+ computed_hash == commitment. hash
182173}
183174
184175fn verify_generation_sig (
@@ -224,7 +215,6 @@ fn print_vec_g1_as_hex(v: &Vec<G1Affine>) {
224215
225216fn compute_agg_key_from_dvt (
226217 verification_vectors : Vec < dvt_abi:: AbiVerificationVector > ,
227- settings : & dvt_abi:: AbiGenerateSettings ,
228218 ids : & Vec < Scalar > ,
229219) -> Result < G1Affine , Box < dyn std:: error:: Error > > {
230220 let verification_vectors: Vec < Vec < G1Affine > > = verification_vectors
@@ -240,12 +230,6 @@ fn compute_agg_key_from_dvt(
240230
241231 let mut all_pts = Vec :: new ( ) ;
242232
243- print ! ( "n = {}, k = {}\n " , settings. n, settings. k) ;
244- print ! (
245- "shares = {}, vectors = {}\n " ,
246- verification_vectors. len( ) ,
247- verification_vectors. len( )
248- ) ;
249233 for i in 0 ..verification_vectors. len ( ) {
250234 let mut pts = Vec :: new ( ) ;
251235 let share_id = ids[ i] ;
@@ -265,9 +249,6 @@ fn compute_agg_key_from_dvt(
265249 final_keys. push ( key) ;
266250 }
267251
268- print ! ( "Final keys: \n " ) ;
269- print_vec_g1_as_hex ( & final_keys) ;
270-
271252 let agg_key = lagrange_interpolation ( & final_keys, & ids) ?;
272253 return Ok ( agg_key) ;
273254}
@@ -277,6 +258,14 @@ pub fn verify_generations(
277258 settings : & dvt_abi:: AbiGenerateSettings ,
278259 agg_key : & dvt_abi:: BLSPubkey ,
279260) -> Result < ( ) , Box < dyn std:: error:: Error > > {
261+
262+ if generations. len ( ) != settings. n as usize {
263+ return Err ( Box :: new ( std:: io:: Error :: new (
264+ std:: io:: ErrorKind :: InvalidData ,
265+ "Invalid number of generations" ,
266+ ) ) ) ;
267+ }
268+
280269 let mut sorted = generations. to_vec ( ) ;
281270 sorted. sort_by ( |a, b| a. base_hash . cmp ( & b. base_hash ) ) ;
282271
@@ -295,15 +284,25 @@ pub fn verify_generations(
295284 . map ( |( i, _) | -> Scalar { bls_id_from_u32 ( ( i + 1 ) as u32 ) } )
296285 . collect ( ) ;
297286
298- let computed_key = compute_agg_key_from_dvt ( verification_vectors, settings , & ids) ?;
287+ let computed_key = compute_agg_key_from_dvt ( verification_vectors, & ids) ?;
299288
300- if computed_key != G1Affine :: from_compressed ( agg_key) . into_option ( ) . unwrap ( ) {
289+ let agg_key = G1Affine :: from_compressed ( agg_key) . into_option ( ) ;
290+
291+ if agg_key. is_none ( ) {
301292 return Err ( Box :: new ( std:: io:: Error :: new (
302293 std:: io:: ErrorKind :: InvalidData ,
303294 "Invalid aggregate public key" ,
304295 ) ) ) ;
305296 }
306297
298+ let agg_key = agg_key. unwrap ( ) ;
299+ if computed_key != agg_key {
300+ return Err ( Box :: new ( std:: io:: Error :: new (
301+ std:: io:: ErrorKind :: InvalidData ,
302+ format ! ( "Computed key {} does not match aggregate public key {}" , hex:: encode( computed_key. to_compressed( ) ) , hex:: encode( agg_key. to_compressed( ) ) ) ,
303+ ) ) ) ;
304+ }
305+
307306 let partial_keys = sorted
308307 . iter ( )
309308 . map ( |generation| -> G1Affine {
@@ -315,31 +314,24 @@ pub fn verify_generations(
315314
316315 let computed_key = lagrange_interpolation ( & partial_keys, & ids) ?;
317316
318- if computed_key != G1Affine :: from_compressed ( agg_key) . into_option ( ) . unwrap ( ) {
317+ if computed_key != agg_key {
319318 return Err ( Box :: new ( std:: io:: Error :: new (
320319 std:: io:: ErrorKind :: InvalidData ,
321- "Invalid aggregate public key" ,
320+ format ! ( "Computed key {} does not match aggregate public key {}" , hex :: encode ( computed_key . to_compressed ( ) ) , hex :: encode ( agg_key . to_compressed ( ) ) ) ,
322321 ) ) ) ;
323322 }
324323
325324 for ( _, generation) in generations. iter ( ) . enumerate ( ) {
326325 verify_generation_sig ( generation) ?;
327326 let initial_commitment = generate_initial_commitment ( generation, & settings) ;
328- let ok = verify_initial_commitment ( & initial_commitment) ;
329- match ok {
330- ProveResult :: SlashableError => {
331- return Err ( Box :: new ( std:: io:: Error :: new (
332- std:: io:: ErrorKind :: InvalidData ,
333- "Slashable error while verifying initial commitment" ,
334- ) ) ) ;
335- }
336- ProveResult :: UnslashableError => {
337- return Err ( Box :: new ( std:: io:: Error :: new (
338- std:: io:: ErrorKind :: InvalidData ,
339- "Unslashable error while verifying initial commitment" ,
340- ) ) ) ;
341- }
342- ProveResult :: Ok => ( ) ,
327+ let ok = verify_initial_commitment_hash ( & initial_commitment) ;
328+ if !ok {
329+ return Err ( Box :: new ( VerificationErrors :: UnslashableError (
330+ String :: from ( format ! (
331+ "Invalid initial commitment hash {}\n " ,
332+ hex:: encode( initial_commitment. hash)
333+ ) ) ,
334+ ) ) ) ;
343335 }
344336 }
345337 Ok ( ( ) )
0 commit comments