From 832b3b0e69fe429b0fb59a79d31739f1ed5752ea Mon Sep 17 00:00:00 2001 From: LStan Date: Mon, 3 Nov 2025 20:32:23 +0700 Subject: [PATCH] SIMD-0334: Fix alt_bn128_pairing syscall length check --- src/ballet/bn254/fd_bn254.c | 8 ++++++-- src/ballet/bn254/fd_bn254.h | 3 ++- src/ballet/bn254/test_bn254.c | 5 +++-- src/flamenco/features/fd_features_generated.c | 8 ++++++++ src/flamenco/features/fd_features_generated.h | 3 ++- src/flamenco/features/feature_map.json | 3 ++- src/flamenco/vm/syscall/fd_vm_syscall_crypto.c | 3 ++- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/ballet/bn254/fd_bn254.c b/src/ballet/bn254/fd_bn254.c index e0876444c72..61c2f12ae2c 100644 --- a/src/ballet/bn254/fd_bn254.c +++ b/src/ballet/bn254/fd_bn254.c @@ -222,13 +222,17 @@ fd_bn254_g1_scalar_mul_syscall( uchar out[64], int fd_bn254_pairing_is_one_syscall( uchar out[32], uchar const in[], - ulong in_sz ) { + ulong in_sz, + int check_correct_sz ) { /* https://github.com/anza-xyz/agave/blob/v1.18.6/sdk/program/src/alt_bn128/mod.rs#L244 Note: this check doesn't do anything because 192usize.checked_rem(192) = Some(0) i.e., this is NOT checking that in_sz % 192 == 0. i.e., this is NOT needed: - if( FD_UNLIKELY( (in_sz%192UL)!=0 ) ) return -1; */ + if( FD_UNLIKELY( (in_sz%192UL)!=0 ) ) return -1; + Update: https://github.com/anza-xyz/solana-sdk/blob/6fde5263/bn254/src/pairing.rs#L66-L83 */ + if( FD_UNLIKELY( check_correct_sz && (in_sz%192UL)!=0 ) ) return -1; + ulong elements_len = in_sz / 192UL; fd_bn254_g1_t p[FD_BN254_PAIRING_BATCH_MAX]; fd_bn254_g2_t q[FD_BN254_PAIRING_BATCH_MAX]; diff --git a/src/ballet/bn254/fd_bn254.h b/src/ballet/bn254/fd_bn254.h index 18fc7c38c8a..c8cfd51e7c3 100644 --- a/src/ballet/bn254/fd_bn254.h +++ b/src/ballet/bn254/fd_bn254.h @@ -25,7 +25,8 @@ fd_bn254_g1_scalar_mul_syscall( uchar out[64], int fd_bn254_pairing_is_one_syscall( uchar out[32], uchar const in[], - ulong in_sz ); + ulong in_sz, + int check_correct_sz ); /* fd_bn254_g1_compress compresses a point in G1. Input in is a 64-byte big endian buffer representing the point (x, y), diff --git a/src/ballet/bn254/test_bn254.c b/src/ballet/bn254/test_bn254.c index 9e15045a326..55323523281 100644 --- a/src/ballet/bn254/test_bn254.c +++ b/src/ballet/bn254/test_bn254.c @@ -339,7 +339,8 @@ int main( int argc, FD_LOG_HEXDUMP_WARNING(( "exp", &in[64], 128 )); FD_LOG_ERR(( "FAIL: test g2 %lu, %s", i, "res != exp" )); } - FD_TEST( fd_bn254_pairing_is_one_syscall( res, in, in_sz )==0 ); + FD_TEST( fd_bn254_pairing_is_one_syscall( res, in, in_sz, 0 )==0 ); + FD_TEST( fd_bn254_pairing_is_one_syscall( res, in, in_sz, 1 )==0 ); fd_hex_decode( exp, tests[2*i+1], 32 ); if( !fd_memeq( res, exp, 32 ) ) { @@ -389,7 +390,7 @@ int main( int argc, ulong iter = 100UL; long dt = fd_log_wallclock(); for( ulong rem=iter; rem; rem-- ) { - fd_bn254_pairing_is_one_syscall( res, in, in_sz ); + fd_bn254_pairing_is_one_syscall( res, in, in_sz, 1 ); } dt = fd_log_wallclock() - dt; log_bench( "fd_bn254_pairing_is_one_syscall", iter, dt ); diff --git a/src/flamenco/features/fd_features_generated.c b/src/flamenco/features/fd_features_generated.c index 4e4f60c674e..8e5acc0a733 100644 --- a/src/flamenco/features/fd_features_generated.c +++ b/src/flamenco/features/fd_features_generated.c @@ -1679,6 +1679,12 @@ fd_feature_id_t const ids[] = { .name = "account_data_direct_mapping", .cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX} }, + { .index = offsetof(fd_features_t, fix_alt_bn128_pairing_length_check)>>3, + .id = {"\x08\xe9\x40\xc0\xc3\x42\x8a\xf0\xbd\x9d\x09\x80\xa6\xce\x78\xcb\x1c\xc6\x57\x4e\x44\xfe\xf5\x52\xe7\x0c\x40\x70\xe9\x51\xec\x74"}, + /* bnYzodLwmybj7e1HAe98yZrdJTd7we69eMMLgCXqKZm */ + .name = "fix_alt_bn128_pairing_length_check", + .cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX} }, + { .index = ULONG_MAX } }; /* TODO replace this with fd_map_perfect */ @@ -1930,6 +1936,7 @@ fd_feature_id_query( ulong prefix ) { case 0x5c64cc1a9be3790a: return &ids[ 242 ]; case 0x90a88c0cfe8bb1b1: return &ids[ 243 ]; case 0xe8604b2d7d45af83: return &ids[ 244 ]; + case 0xf08a42c3c040e908: return &ids[ 245 ]; default: break; } return NULL; @@ -2180,4 +2187,5 @@ FD_STATIC_ASSERT( offsetof( fd_features_t, enshrine_slashing_program FD_STATIC_ASSERT( offsetof( fd_features_t, raise_account_cu_limit )>>3==242UL, layout ); FD_STATIC_ASSERT( offsetof( fd_features_t, stricter_abi_and_runtime_constraints )>>3==243UL, layout ); FD_STATIC_ASSERT( offsetof( fd_features_t, account_data_direct_mapping )>>3==244UL, layout ); +FD_STATIC_ASSERT( offsetof( fd_features_t, fix_alt_bn128_pairing_length_check )>>3==245UL, layout ); FD_STATIC_ASSERT( sizeof( fd_features_t )>>3==FD_FEATURE_ID_CNT, layout ); diff --git a/src/flamenco/features/fd_features_generated.h b/src/flamenco/features/fd_features_generated.h index a0c3b74334f..4315df3a6e1 100644 --- a/src/flamenco/features/fd_features_generated.h +++ b/src/flamenco/features/fd_features_generated.h @@ -8,7 +8,7 @@ #endif /* FEATURE_ID_CNT is the number of features in ids */ -#define FD_FEATURE_ID_CNT (245UL) +#define FD_FEATURE_ID_CNT (246UL) union fd_features { ulong f[ FD_FEATURE_ID_CNT ]; struct { @@ -257,5 +257,6 @@ union fd_features { /* 0x5c64cc1a9be3790a */ ulong raise_account_cu_limit; /* 0x90a88c0cfe8bb1b1 */ ulong stricter_abi_and_runtime_constraints; /* 0xe8604b2d7d45af83 */ ulong account_data_direct_mapping; + /* 0xf08a42c3c040e908 */ ulong fix_alt_bn128_pairing_length_check; }; }; diff --git a/src/flamenco/features/feature_map.json b/src/flamenco/features/feature_map.json index c23bb1325e0..304349f44e1 100644 --- a/src/flamenco/features/feature_map.json +++ b/src/flamenco/features/feature_map.json @@ -243,5 +243,6 @@ {"name":"enshrine_slashing_program","pubkey":"sProgVaNWkYdP2eTRAy1CPrgb3b9p8yXCASrPEqo6VJ"}, {"name":"raise_account_cu_limit","pubkey":"htsptAwi2yRoZH83SKaUXykeZGtZHgxkS2QwW1pssR8"}, {"name":"stricter_abi_and_runtime_constraints","pubkey":"CxeBn9PVeeXbmjbNwLv6U4C6svNxnC4JX6mfkvgeMocM"}, - {"name":"account_data_direct_mapping","pubkey":"9s3RKimHWS44rJcJ9P1rwCmn2TvMqtZQBmz815ZUUHqJ"} + {"name":"account_data_direct_mapping","pubkey":"9s3RKimHWS44rJcJ9P1rwCmn2TvMqtZQBmz815ZUUHqJ"}, + {"name":"fix_alt_bn128_pairing_length_check","pubkey":"bnYzodLwmybj7e1HAe98yZrdJTd7we69eMMLgCXqKZm"} ] diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_crypto.c b/src/flamenco/vm/syscall/fd_vm_syscall_crypto.c index 10ead3e3cc9..f2ccf4e3daa 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_crypto.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_crypto.c @@ -88,7 +88,8 @@ fd_vm_syscall_sol_alt_bn128_group_op( void * _vm, case FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING: /* Compute pairing */ - if( FD_LIKELY( fd_bn254_pairing_is_one_syscall( call_result, input, input_sz )==0 ) ) { + if( FD_LIKELY( fd_bn254_pairing_is_one_syscall( call_result, input, input_sz, + FD_FEATURE_ACTIVE( vm->instr_ctx->txn_ctx->slot, &vm->instr_ctx->txn_ctx->features, fix_alt_bn128_pairing_length_check ) )==0 ) ) { ret = 0UL; /* success */ } break;