@@ -1139,6 +1139,17 @@ declare_builtin_function!(
11391139        use  solana_zk_token_sdk:: curve25519:: { 
11401140            curve_syscall_traits:: * ,  edwards,  ristretto,  scalar, 
11411141        } ; 
1142+ 
1143+         let  restrict_msm_length = invoke_context
1144+             . feature_set
1145+             . is_active( & feature_set:: curve25519_restrict_msm_length:: id( ) ) ; 
1146+         #[ allow( clippy:: collapsible_if) ] 
1147+         if  restrict_msm_length { 
1148+             if  points_len > 512  { 
1149+                 return  Err ( Box :: new( SyscallError :: InvalidLength ) ) ; 
1150+             } 
1151+         } 
1152+ 
11421153        match  curve_id { 
11431154            CURVE25519_EDWARDS  => { 
11441155                let  cost = invoke_context
@@ -3146,6 +3157,122 @@ mod tests {
31463157        assert_eq ! ( expected_product,  result_point) ; 
31473158    } 
31483159
3160+     #[ test]  
3161+     fn  test_syscall_multiscalar_multiplication_maximum_length_exceeded ( )  { 
3162+         use  solana_zk_token_sdk:: curve25519:: curve_syscall_traits:: { 
3163+             CURVE25519_EDWARDS ,  CURVE25519_RISTRETTO , 
3164+         } ; 
3165+ 
3166+         let  config = Config :: default ( ) ; 
3167+         prepare_mockup ! ( invoke_context,  program_id,  bpf_loader:: id( ) ) ; 
3168+ 
3169+         let  scalar:  [ u8 ;  32 ]  = [ 
3170+             254 ,  198 ,  23 ,  138 ,  67 ,  243 ,  184 ,  110 ,  236 ,  115 ,  236 ,  205 ,  205 ,  215 ,  79 ,  114 ,  45 ,  250 , 
3171+             78 ,  137 ,  3 ,  107 ,  136 ,  237 ,  49 ,  126 ,  117 ,  223 ,  37 ,  191 ,  88 ,  6 , 
3172+         ] ; 
3173+         let  scalars = [ scalar;  513 ] ; 
3174+         let  scalars_va = 0x100000000 ; 
3175+ 
3176+         let  edwards_point:  [ u8 ;  32 ]  = [ 
3177+             252 ,  31 ,  230 ,  46 ,  173 ,  95 ,  144 ,  148 ,  158 ,  157 ,  63 ,  10 ,  8 ,  68 ,  58 ,  176 ,  142 ,  192 ,  168 , 
3178+             53 ,  61 ,  105 ,  194 ,  166 ,  43 ,  56 ,  246 ,  236 ,  28 ,  146 ,  114 ,  133 , 
3179+         ] ; 
3180+         let  edwards_points = [ edwards_point;  513 ] ; 
3181+         let  edwards_points_va = 0x200000000 ; 
3182+ 
3183+         let  ristretto_point:  [ u8 ;  32 ]  = [ 
3184+             130 ,  35 ,  97 ,  25 ,  18 ,  199 ,  33 ,  239 ,  85 ,  143 ,  119 ,  111 ,  49 ,  51 ,  224 ,  40 ,  167 ,  185 ,  240 , 
3185+             179 ,  25 ,  194 ,  213 ,  41 ,  14 ,  155 ,  104 ,  18 ,  181 ,  197 ,  15 ,  112 , 
3186+         ] ; 
3187+         let  ristretto_points = [ ristretto_point;  513 ] ; 
3188+         let  ristretto_points_va = 0x300000000 ; 
3189+ 
3190+         let  mut  result_point:  [ u8 ;  32 ]  = [ 0 ;  32 ] ; 
3191+         let  result_point_va = 0x400000000 ; 
3192+ 
3193+         let  mut  memory_mapping = MemoryMapping :: new ( 
3194+             vec ! [ 
3195+                 MemoryRegion :: new_readonly( bytes_of_slice( & scalars) ,  scalars_va) , 
3196+                 MemoryRegion :: new_readonly( bytes_of_slice( & edwards_points) ,  edwards_points_va) , 
3197+                 MemoryRegion :: new_readonly( bytes_of_slice( & ristretto_points) ,  ristretto_points_va) , 
3198+                 MemoryRegion :: new_writable( bytes_of_slice_mut( & mut  result_point) ,  result_point_va) , 
3199+             ] , 
3200+             & config, 
3201+             & SBPFVersion :: V2 , 
3202+         ) 
3203+         . unwrap ( ) ; 
3204+ 
3205+         // test Edwards 
3206+         invoke_context. mock_set_remaining ( 500_000 ) ; 
3207+         let  result = SyscallCurveMultiscalarMultiplication :: rust ( 
3208+             & mut  invoke_context, 
3209+             CURVE25519_EDWARDS , 
3210+             scalars_va, 
3211+             edwards_points_va, 
3212+             512 ,  // below maximum vector length 
3213+             result_point_va, 
3214+             & mut  memory_mapping, 
3215+         ) ; 
3216+ 
3217+         assert_eq ! ( 0 ,  result. unwrap( ) ) ; 
3218+         let  expected_product = [ 
3219+             20 ,  146 ,  226 ,  37 ,  22 ,  61 ,  86 ,  249 ,  208 ,  40 ,  38 ,  11 ,  126 ,  101 ,  10 ,  82 ,  81 ,  77 ,  88 ,  209 , 
3220+             15 ,  76 ,  82 ,  251 ,  180 ,  133 ,  84 ,  243 ,  162 ,  0 ,  11 ,  145 , 
3221+         ] ; 
3222+         assert_eq ! ( expected_product,  result_point) ; 
3223+ 
3224+         invoke_context. mock_set_remaining ( 500_000 ) ; 
3225+         let  result = SyscallCurveMultiscalarMultiplication :: rust ( 
3226+             & mut  invoke_context, 
3227+             CURVE25519_EDWARDS , 
3228+             scalars_va, 
3229+             edwards_points_va, 
3230+             513 ,  // above maximum vector length 
3231+             result_point_va, 
3232+             & mut  memory_mapping, 
3233+         ) 
3234+         . unwrap_err ( ) 
3235+         . downcast :: < SyscallError > ( ) 
3236+         . unwrap ( ) ; 
3237+ 
3238+         assert_eq ! ( * result,  SyscallError :: InvalidLength ) ; 
3239+ 
3240+         // test Ristretto 
3241+         invoke_context. mock_set_remaining ( 500_000 ) ; 
3242+         let  result = SyscallCurveMultiscalarMultiplication :: rust ( 
3243+             & mut  invoke_context, 
3244+             CURVE25519_RISTRETTO , 
3245+             scalars_va, 
3246+             ristretto_points_va, 
3247+             512 ,  // below maximum vector length 
3248+             result_point_va, 
3249+             & mut  memory_mapping, 
3250+         ) ; 
3251+ 
3252+         assert_eq ! ( 0 ,  result. unwrap( ) ) ; 
3253+         let  expected_product = [ 
3254+             146 ,  224 ,  127 ,  193 ,  252 ,  64 ,  196 ,  181 ,  246 ,  104 ,  27 ,  116 ,  183 ,  52 ,  200 ,  239 ,  2 ,  108 , 
3255+             21 ,  27 ,  97 ,  44 ,  95 ,  65 ,  26 ,  218 ,  223 ,  39 ,  197 ,  132 ,  51 ,  49 , 
3256+         ] ; 
3257+         assert_eq ! ( expected_product,  result_point) ; 
3258+ 
3259+         invoke_context. mock_set_remaining ( 500_000 ) ; 
3260+         let  result = SyscallCurveMultiscalarMultiplication :: rust ( 
3261+             & mut  invoke_context, 
3262+             CURVE25519_RISTRETTO , 
3263+             scalars_va, 
3264+             ristretto_points_va, 
3265+             513 ,  // above maximum vector length 
3266+             result_point_va, 
3267+             & mut  memory_mapping, 
3268+         ) 
3269+         . unwrap_err ( ) 
3270+         . downcast :: < SyscallError > ( ) 
3271+         . unwrap ( ) ; 
3272+ 
3273+         assert_eq ! ( * result,  SyscallError :: InvalidLength ) ; 
3274+     } 
3275+ 
31493276    fn  create_filled_type < T :  Default > ( zero_init :  bool )  -> T  { 
31503277        let  mut  val = T :: default ( ) ; 
31513278        let  p = & mut  val as  * mut  _  as  * mut  u8 ; 
0 commit comments