@@ -387,43 +387,89 @@ impl FeeTable {
387387 // - For sizes less than 1024, instruction count remains the same.
388388 // - For greater sizes following linear equation might be applied:
389389 // (used: https://www.socscistatistics.com/tests/regression/default.aspx)
390- // instructions_cnt = 34.55672 * size + 10577803.13
390+ // instructions_cnt = 35.83223 * size + 15563087.39
391391 // Lets round:
392- // 34.55672 -> 35
393- // 10577803.13 -> 10577804
392+ // 35.83223 -> 36
393+ // 15563087.39 -> 15650000 (increased slightly to get the positive difference between
394+ // calculated and measured number of instructions)
394395 let size = if size < 1024 { 1024 } else { cast ( size) } ;
395- let instructions_cnt = add ( mul ( size, 35 ) , 10577804 ) ;
396+ let instructions_cnt = add ( mul ( size, 36 ) , 15650000 ) ;
396397 // Convert to cost units
397398 instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT
398399 }
399400
400401 #[ inline]
401402 pub fn bls12381_v1_aggregate_verify_cost ( & self , sizes : & [ usize ] ) -> u32 {
402- // Below approach does not take aggregation into account.
403- // Summing costs pers size gives greater values.
404- // We've found somewhat difficult to find a proper and effective equation to estimate
405- // the instructions count collected with `test_crypto_scrypto_verify_bls12381_v1_costing`
406- // TODO: Find more adequate cost estimation
407- let mut cost: u32 = 0 ;
408- for size in sizes {
409- cost += self . bls12381_v1_verify_cost ( * size) ;
403+ // Observed that aggregated verify might be broken down into:
404+ // - steps depending on message size
405+ // - aggregation of pairings of each corresponding key and message pair
406+ // - commit each above aggregation
407+ // - steps that do not depend on message size
408+ // - read signature from bytes: 281125 instructions
409+ // - signature validation: 583573 instructions
410+ // - aggregated pairing of signature to verify and initialization point: 3027639 instructions
411+ // - final verification: 4280077 instructions
412+ //
413+ // more details and data in https://docs.google.com/spreadsheets/d/1rV0KyB7UQrg2tOenbh2MQ1fo9MXwrwPFW4l0_CVO-6o/edit?usp=sharing
414+
415+ // Pairing aggregate
416+ // Following linerar equation might be applied:
417+ // (used: https://www.socscistatistics.com/tests/regression/default.aspx)
418+ // instructions_cnt = 34.42199 * size + 2620295.64271
419+ // Lets round:
420+ // 34.42199 -> 35
421+ // 2620295.64271 -> 2620296
422+ //
423+ // Also observed that additional 16850000 instructions are performed
424+ // every multiple of 8
425+ let mut instructions_cnt = 0u32 ;
426+
427+ for s in sizes {
428+ instructions_cnt = add ( add ( instructions_cnt, mul ( 35 , cast ( * s) ) ) , 2620296 ) ;
410429 }
411- cost
430+ let multiplier = cast ( sizes. len ( ) / 8 ) ;
431+ instructions_cnt = add ( instructions_cnt, mul ( multiplier, 16850000 ) ) ;
432+
433+ // Pairing commit
434+ // Observed that number commit instructions repeats every multiple of 8
435+ instructions_cnt = add (
436+ instructions_cnt,
437+ match sizes. len ( ) % 8 {
438+ 0 => 0 ,
439+ 1 => 3051556 ,
440+ 2 => 5020768 ,
441+ 3 => 6990111 ,
442+ 4 => 8959454 ,
443+ 5 => 10928798 ,
444+ 6 => 12898141 ,
445+ 7 => 14867484 ,
446+ _ => unreachable ! ( ) ,
447+ } ,
448+ ) ;
449+
450+ // Instructions that do not depend on size
451+ instructions_cnt = add ( instructions_cnt, 281125 + 583573 + 3027639 + 4280077 ) ;
452+
453+ // Observed that threaded takes ~1.21 more instructions than no threaded
454+ instructions_cnt = mul ( instructions_cnt / 100 , 121 ) ;
455+ // Convert to cost units
456+ instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT
412457 }
413458
414459 #[ inline]
415460 pub fn bls12381_v1_fast_aggregate_verify_cost ( & self , size : usize , keys_cnt : usize ) -> u32 {
416461 // Based on `test_crypto_scrypto_bls12381_v1_fast_aggregate_verify_costing`
417462 // - For sizes less than 1024, instruction count remains the same.
418463 // - For greater sizes following linear equation might be applied:
419- // instructions_cnt = 32.1717 * size + 624919.5254 * keys_cnt + 9058827.9112
464+ // instructions_cnt = 35.008 * size + 626055.4801 * keys_cnt + 15125588.5419
420465 // (used: https://www.socscistatistics.com/tests/multipleregression/default.aspx)
421466 // Lets round:
422- // 32.1717 -> 33
423- // 624919.5254 -> 624920
424- // 10096964.55 -> 10096965
467+ // 35.008 -> 36
468+ // 626055.4801 -> 626056
469+ // 15125588.5419 -> 15200000 (increased slightly to get the positive difference between
470+ // calculated and measured number of instructions)
425471 let size = if size < 1024 { 1024 } else { cast ( size) } ;
426- let instructions_cnt = add ( add ( mul ( size, 33 ) , mul ( cast ( keys_cnt) , 624920 ) ) , 10096965 ) ;
472+ let instructions_cnt = add ( add ( mul ( size, 36 ) , mul ( cast ( keys_cnt) , 626056 ) ) , 15200000 ) ;
427473 // Convert to cost units
428474 instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT
429475 }
@@ -436,8 +482,9 @@ impl FeeTable {
436482 // (used: https://www.socscistatistics.com/tests/regression/default.aspx)
437483 // Lets round:
438484 // 879553.91557 -> 879554
439- // 567872.5895 -> 567873
440- let instructions_cnt = sub ( mul ( cast ( signatures_cnt) , 879554 ) , 567873 ) ;
485+ // 567872.5895 -> 500000 (decreased to get more accurate difference between calculated
486+ // and measured instructions)
487+ let instructions_cnt = sub ( mul ( cast ( signatures_cnt) , 879554 ) , 500000 ) ;
441488 // Convert to cost units
442489 instructions_cnt / CPU_INSTRUCTIONS_TO_COST_UNIT
443490 }
0 commit comments