Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 7e18276

Browse files
v1.17: [zk-token-sdk] Restrict Edwards and Ristretto multiscalar multiplication vector length to at most 512 (backport of #34763) (#34849)
* [zk-token-sdk] Restrict Edwards and Ristretto multiscalar multiplication vector length to at most 512 (#34763) * restrict curve25519 multiscalar multiplication vector length to 512 * add syscall tests for msm vector length * add new feature gate `curve25519_restrict_msm_length` * update tests for feature new gate * Update programs/bpf_loader/src/syscalls/mod.rs Co-authored-by: Trent Nelson <[email protected]> * remove length guard on the multisicalar mult lib function --------- Co-authored-by: Trent Nelson <[email protected]> (cherry picked from commit 7321859) # Conflicts: # sdk/src/feature_set.rs * resolve conflict --------- Co-authored-by: samkim-crypto <[email protected]>
1 parent d878262 commit 7e18276

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

programs/bpf_loader/src/syscalls/mod.rs

+127
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,17 @@ declare_builtin_function!(
11711171
use solana_zk_token_sdk::curve25519::{
11721172
curve_syscall_traits::*, edwards, ristretto, scalar,
11731173
};
1174+
1175+
let restrict_msm_length = invoke_context
1176+
.feature_set
1177+
.is_active(&feature_set::curve25519_restrict_msm_length::id());
1178+
#[allow(clippy::collapsible_if)]
1179+
if restrict_msm_length {
1180+
if points_len > 512 {
1181+
return Err(Box::new(SyscallError::InvalidLength));
1182+
}
1183+
}
1184+
11741185
match curve_id {
11751186
CURVE25519_EDWARDS => {
11761187
let cost = invoke_context
@@ -3211,6 +3222,122 @@ mod tests {
32113222
assert_eq!(expected_product, result_point);
32123223
}
32133224

3225+
#[test]
3226+
fn test_syscall_multiscalar_multiplication_maximum_length_exceeded() {
3227+
use solana_zk_token_sdk::curve25519::curve_syscall_traits::{
3228+
CURVE25519_EDWARDS, CURVE25519_RISTRETTO,
3229+
};
3230+
3231+
let config = Config::default();
3232+
prepare_mockup!(invoke_context, program_id, bpf_loader::id());
3233+
3234+
let scalar: [u8; 32] = [
3235+
254, 198, 23, 138, 67, 243, 184, 110, 236, 115, 236, 205, 205, 215, 79, 114, 45, 250,
3236+
78, 137, 3, 107, 136, 237, 49, 126, 117, 223, 37, 191, 88, 6,
3237+
];
3238+
let scalars = [scalar; 513];
3239+
let scalars_va = 0x100000000;
3240+
3241+
let edwards_point: [u8; 32] = [
3242+
252, 31, 230, 46, 173, 95, 144, 148, 158, 157, 63, 10, 8, 68, 58, 176, 142, 192, 168,
3243+
53, 61, 105, 194, 166, 43, 56, 246, 236, 28, 146, 114, 133,
3244+
];
3245+
let edwards_points = [edwards_point; 513];
3246+
let edwards_points_va = 0x200000000;
3247+
3248+
let ristretto_point: [u8; 32] = [
3249+
130, 35, 97, 25, 18, 199, 33, 239, 85, 143, 119, 111, 49, 51, 224, 40, 167, 185, 240,
3250+
179, 25, 194, 213, 41, 14, 155, 104, 18, 181, 197, 15, 112,
3251+
];
3252+
let ristretto_points = [ristretto_point; 513];
3253+
let ristretto_points_va = 0x300000000;
3254+
3255+
let mut result_point: [u8; 32] = [0; 32];
3256+
let result_point_va = 0x400000000;
3257+
3258+
let mut memory_mapping = MemoryMapping::new(
3259+
vec![
3260+
MemoryRegion::new_readonly(bytes_of_slice(&scalars), scalars_va),
3261+
MemoryRegion::new_readonly(bytes_of_slice(&edwards_points), edwards_points_va),
3262+
MemoryRegion::new_readonly(bytes_of_slice(&ristretto_points), ristretto_points_va),
3263+
MemoryRegion::new_writable(bytes_of_slice_mut(&mut result_point), result_point_va),
3264+
],
3265+
&config,
3266+
&SBPFVersion::V2,
3267+
)
3268+
.unwrap();
3269+
3270+
// test Edwards
3271+
invoke_context.mock_set_remaining(500_000);
3272+
let result = SyscallCurveMultiscalarMultiplication::rust(
3273+
&mut invoke_context,
3274+
CURVE25519_EDWARDS,
3275+
scalars_va,
3276+
edwards_points_va,
3277+
512, // below maximum vector length
3278+
result_point_va,
3279+
&mut memory_mapping,
3280+
);
3281+
3282+
assert_eq!(0, result.unwrap());
3283+
let expected_product = [
3284+
20, 146, 226, 37, 22, 61, 86, 249, 208, 40, 38, 11, 126, 101, 10, 82, 81, 77, 88, 209,
3285+
15, 76, 82, 251, 180, 133, 84, 243, 162, 0, 11, 145,
3286+
];
3287+
assert_eq!(expected_product, result_point);
3288+
3289+
invoke_context.mock_set_remaining(500_000);
3290+
let result = SyscallCurveMultiscalarMultiplication::rust(
3291+
&mut invoke_context,
3292+
CURVE25519_EDWARDS,
3293+
scalars_va,
3294+
edwards_points_va,
3295+
513, // above maximum vector length
3296+
result_point_va,
3297+
&mut memory_mapping,
3298+
)
3299+
.unwrap_err()
3300+
.downcast::<SyscallError>()
3301+
.unwrap();
3302+
3303+
assert_eq!(*result, SyscallError::InvalidLength);
3304+
3305+
// test Ristretto
3306+
invoke_context.mock_set_remaining(500_000);
3307+
let result = SyscallCurveMultiscalarMultiplication::rust(
3308+
&mut invoke_context,
3309+
CURVE25519_RISTRETTO,
3310+
scalars_va,
3311+
ristretto_points_va,
3312+
512, // below maximum vector length
3313+
result_point_va,
3314+
&mut memory_mapping,
3315+
);
3316+
3317+
assert_eq!(0, result.unwrap());
3318+
let expected_product = [
3319+
146, 224, 127, 193, 252, 64, 196, 181, 246, 104, 27, 116, 183, 52, 200, 239, 2, 108,
3320+
21, 27, 97, 44, 95, 65, 26, 218, 223, 39, 197, 132, 51, 49,
3321+
];
3322+
assert_eq!(expected_product, result_point);
3323+
3324+
invoke_context.mock_set_remaining(500_000);
3325+
let result = SyscallCurveMultiscalarMultiplication::rust(
3326+
&mut invoke_context,
3327+
CURVE25519_RISTRETTO,
3328+
scalars_va,
3329+
ristretto_points_va,
3330+
513, // above maximum vector length
3331+
result_point_va,
3332+
&mut memory_mapping,
3333+
)
3334+
.unwrap_err()
3335+
.downcast::<SyscallError>()
3336+
.unwrap();
3337+
3338+
assert_eq!(*result, SyscallError::InvalidLength);
3339+
}
3340+
32143341
fn create_filled_type<T: Default>(zero_init: bool) -> T {
32153342
let mut val = T::default();
32163343
let p = &mut val as *mut _ as *mut u8;

sdk/src/feature_set.rs

+5
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ pub mod curve25519_syscall_enabled {
146146
solana_sdk::declare_id!("7rcw5UtqgDTBBv2EcynNfYckgdAaH1MAsCjKgXMkN7Ri");
147147
}
148148

149+
pub mod curve25519_restrict_msm_length {
150+
solana_sdk::declare_id!("eca6zf6JJRjQsYYPkBHF3N32MTzur4n2WL4QiiacPCL");
151+
}
152+
149153
pub mod versioned_tx_message_enabled {
150154
solana_sdk::declare_id!("3KZZ6Ks1885aGBQ45fwRcPXVBCtzUvxhUTkwKMR41Tca");
151155
}
@@ -920,6 +924,7 @@ lazy_static! {
920924
(drop_legacy_shreds::id(), "drops legacy shreds #34328"),
921925
(consume_blockstore_duplicate_proofs::id(), "consume duplicate proofs from blockstore in consensus #34372"),
922926
(index_erasure_conflict_duplicate_proofs::id(), "generate duplicate proofs for index and erasure conflicts #34360"),
927+
(curve25519_restrict_msm_length::id(), "restrict curve25519 multiscalar multiplication vector lengths #34763"),
923928
/*************** ADD NEW FEATURES HERE ***************/
924929
]
925930
.iter()

0 commit comments

Comments
 (0)