Skip to content

Commit 3d57ce3

Browse files
authored
alt_bn128 pairing (#7217)
1 parent f86def8 commit 3d57ce3

File tree

7 files changed

+33
-14
lines changed

7 files changed

+33
-14
lines changed

src/ballet/bn254/fd_bn254.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,18 @@ fd_bn254_g1_scalar_mul_syscall( uchar out[64],
222222
int
223223
fd_bn254_pairing_is_one_syscall( uchar out[32],
224224
uchar const in[],
225-
ulong in_sz ) {
225+
ulong in_sz,
226+
int check_len ) {
226227
/* https://github.com/anza-xyz/agave/blob/v1.18.6/sdk/program/src/alt_bn128/mod.rs#L244
227-
Note: this check doesn't do anything because
228-
192usize.checked_rem(192) = Some(0)
229-
i.e., this is NOT checking that in_sz % 192 == 0.
230-
i.e., this is NOT needed:
231-
if( FD_UNLIKELY( (in_sz%192UL)!=0 ) ) return -1; */
228+
Note: Solana had a bug where it checked if input.len().checked_rem(192).is_none(),
229+
which only fails when dividing by zero, so the check never triggered.
230+
When check_len is true, we properly validate that input size is a multiple of 192.
231+
This corresponds to the fix_alt_bn128_pairing_length_check feature gate. */
232+
if( check_len ) {
233+
if( FD_UNLIKELY( (in_sz % 192UL) != 0 ) ) {
234+
return -1; /* Invalid input length */
235+
}
236+
}
232237
ulong elements_len = in_sz / 192UL;
233238
fd_bn254_g1_t p[FD_BN254_PAIRING_BATCH_MAX];
234239
fd_bn254_g2_t q[FD_BN254_PAIRING_BATCH_MAX];

src/ballet/bn254/fd_bn254.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ fd_bn254_g1_scalar_mul_syscall( uchar out[64],
2525
int
2626
fd_bn254_pairing_is_one_syscall( uchar out[32],
2727
uchar const in[],
28-
ulong in_sz );
28+
ulong in_sz,
29+
int check_len );
2930

3031
/* fd_bn254_g1_compress compresses a point in G1.
3132
Input in is a 64-byte big endian buffer representing the point (x, y),

src/ballet/bn254/test_bn254.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ int main( int argc,
339339
FD_LOG_HEXDUMP_WARNING(( "exp", &in[64], 128 ));
340340
FD_LOG_ERR(( "FAIL: test g2 %lu, %s", i, "res != exp" ));
341341
}
342-
FD_TEST( fd_bn254_pairing_is_one_syscall( res, in, in_sz )==0 );
342+
FD_TEST( fd_bn254_pairing_is_one_syscall( res, in, in_sz, 0 /* no length check */ )==0 );
343343

344344
fd_hex_decode( exp, tests[2*i+1], 32 );
345345
if( !fd_memeq( res, exp, 32 ) ) {
@@ -389,7 +389,7 @@ int main( int argc,
389389
ulong iter = 100UL;
390390
long dt = fd_log_wallclock();
391391
for( ulong rem=iter; rem; rem-- ) {
392-
fd_bn254_pairing_is_one_syscall( res, in, in_sz );
392+
fd_bn254_pairing_is_one_syscall( res, in, in_sz, 0 /* no length check */ );
393393
}
394394
dt = fd_log_wallclock() - dt;
395395
log_bench( "fd_bn254_pairing_is_one_syscall", iter, dt );

src/flamenco/features/fd_features_generated.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,13 @@ fd_feature_id_t const ids[] = {
16791679
.name = "account_data_direct_mapping",
16801680
.cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX} },
16811681

1682+
{ .index = offsetof(fd_features_t, fix_alt_bn128_pairing_length_check)>>3,
1683+
.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"},
1684+
/* bnYzodLwmybj7e1HAe98yZrdJTd7we69eMMLgCXqKZm */
1685+
.name = "fix_alt_bn128_pairing_length_check",
1686+
.cleaned_up = {UINT_MAX, UINT_MAX, UINT_MAX},
1687+
.hardcode_for_fuzzing = 1 },
1688+
16821689
{ .index = ULONG_MAX }
16831690
};
16841691
/* TODO replace this with fd_map_perfect */
@@ -1930,6 +1937,7 @@ fd_feature_id_query( ulong prefix ) {
19301937
case 0x5c64cc1a9be3790a: return &ids[ 242 ];
19311938
case 0x90a88c0cfe8bb1b1: return &ids[ 243 ];
19321939
case 0xe8604b2d7d45af83: return &ids[ 244 ];
1940+
case 0xf08a42c3c040e908: return &ids[ 245 ];
19331941
default: break;
19341942
}
19351943
return NULL;
@@ -2180,4 +2188,5 @@ FD_STATIC_ASSERT( offsetof( fd_features_t, enshrine_slashing_program
21802188
FD_STATIC_ASSERT( offsetof( fd_features_t, raise_account_cu_limit )>>3==242UL, layout );
21812189
FD_STATIC_ASSERT( offsetof( fd_features_t, stricter_abi_and_runtime_constraints )>>3==243UL, layout );
21822190
FD_STATIC_ASSERT( offsetof( fd_features_t, account_data_direct_mapping )>>3==244UL, layout );
2191+
FD_STATIC_ASSERT( offsetof( fd_features_t, fix_alt_bn128_pairing_length_check )>>3==245UL, layout );
21832192
FD_STATIC_ASSERT( sizeof( fd_features_t )>>3==FD_FEATURE_ID_CNT, layout );

src/flamenco/features/fd_features_generated.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
#endif
99

1010
/* FEATURE_ID_CNT is the number of features in ids */
11-
#define FD_FEATURE_ID_CNT (245UL)
11+
#define FD_FEATURE_ID_CNT (246UL)
1212

1313
/* Feature set ID calculated from all feature names */
14-
#define FD_FEATURE_SET_ID (2404396587U)
14+
#define FD_FEATURE_SET_ID (2363000211U)
1515

1616
union fd_features {
1717
ulong f[ FD_FEATURE_ID_CNT ];
@@ -261,5 +261,6 @@ union fd_features {
261261
/* 0x5c64cc1a9be3790a */ ulong raise_account_cu_limit;
262262
/* 0x90a88c0cfe8bb1b1 */ ulong stricter_abi_and_runtime_constraints;
263263
/* 0xe8604b2d7d45af83 */ ulong account_data_direct_mapping;
264+
/* 0xf08a42c3c040e908 */ ulong fix_alt_bn128_pairing_length_check;
264265
};
265266
};

src/flamenco/features/feature_map.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,5 +243,6 @@
243243
{"name":"enshrine_slashing_program","pubkey":"sProgVaNWkYdP2eTRAy1CPrgb3b9p8yXCASrPEqo6VJ"},
244244
{"name":"raise_account_cu_limit","pubkey":"htsptAwi2yRoZH83SKaUXykeZGtZHgxkS2QwW1pssR8"},
245245
{"name":"stricter_abi_and_runtime_constraints","pubkey":"CxeBn9PVeeXbmjbNwLv6U4C6svNxnC4JX6mfkvgeMocM"},
246-
{"name":"account_data_direct_mapping","pubkey":"9s3RKimHWS44rJcJ9P1rwCmn2TvMqtZQBmz815ZUUHqJ"}
246+
{"name":"account_data_direct_mapping","pubkey":"9s3RKimHWS44rJcJ9P1rwCmn2TvMqtZQBmz815ZUUHqJ"},
247+
{"name":"fix_alt_bn128_pairing_length_check","pubkey":"bnYzodLwmybj7e1HAe98yZrdJTd7we69eMMLgCXqKZm","hardcode_for_fuzzing":1}
247248
]

src/flamenco/vm/syscall/fd_vm_syscall_crypto.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ fd_vm_syscall_sol_alt_bn128_group_op( void * _vm,
8888
break;
8989

9090
case FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING:
91-
/* Compute pairing */
92-
if( FD_LIKELY( fd_bn254_pairing_is_one_syscall( call_result, input, input_sz )==0 ) ) {
91+
/* Compute pairing with length check based on feature gate.
92+
https://github.com/anza-xyz/solana-sdk/blob/bn254%40v3.1.2/bn254/src/pairing.rs#L76-L82 */
93+
if( FD_LIKELY( fd_bn254_pairing_is_one_syscall( call_result, input, input_sz,
94+
FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->txn_ctx->bank, fix_alt_bn128_pairing_length_check ) )==0 ) ) {
9395
ret = 0UL; /* success */
9496
}
9597
break;

0 commit comments

Comments
 (0)