Big integer modular exponentiation (EIP-198) (#28503)

* big_mod_exp impl

* fix programs/sbf/Cargo.lock

* ComputeBudget impl

* update compute_budget

* compute_budget update

* fix build

* fix tests

* fix cargo clippy

* fix clippy

* fix bpf_loader dependency sorting

* fix sorting

* fix merge from master

* fix cargo fmt

* fix C-tests

* fix cargo fmt

* comments apply

* fix programs/sbf/Cargo.lock

* update compude_budget cost

* remove whitespaces

* fix cargo fmt

Co-authored-by: sinev-valentine <sinev-valentine@yandex.ru>
This commit is contained in:
valiksinev 2023-01-20 12:42:37 +03:00 committed by GitHub
parent 9a5aca36e6
commit 5f7fea100a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 528 additions and 2 deletions

1
Cargo.lock generated
View File

@ -5986,6 +5986,7 @@ dependencies = [
"libsecp256k1",
"log",
"memoffset",
"num-bigint 0.4.3",
"num-derive",
"num-traits",
"parking_lot 0.12.1",

View File

@ -107,6 +107,8 @@ pub struct ComputeBudget {
/// + alt_bn128_pairing_one_pair_cost_other * (num_elems - 1)
pub alt_bn128_pairing_one_pair_cost_first: u64,
pub alt_bn128_pairing_one_pair_cost_other: u64,
/// Big integer modular exponentiation cost
pub big_modular_exponentiation_cost: u64,
}
impl Default for ComputeBudget {
@ -154,6 +156,7 @@ impl ComputeBudget {
alt_bn128_multiplication_cost: 3_840,
alt_bn128_pairing_one_pair_cost_first: 36_364,
alt_bn128_pairing_one_pair_cost_other: 12_121,
big_modular_exponentiation_cost: 33,
}
}

View File

@ -29,13 +29,14 @@ use {
ALT_BN128_ADDITION_OUTPUT_LEN, ALT_BN128_MULTIPLICATION_OUTPUT_LEN,
ALT_BN128_PAIRING_ELEMENT_LEN, ALT_BN128_PAIRING_OUTPUT_LEN,
},
big_mod_exp::{big_mod_exp, BigModExpParams},
blake3, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable,
entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS},
feature_set::FeatureSet,
feature_set::{
self, blake3_syscall_enabled, check_syscall_outputs_do_not_overlap,
curve25519_syscall_enabled, disable_cpi_setting_executable_and_rent_epoch,
disable_fees_sysvar, enable_alt_bn128_syscall,
disable_fees_sysvar, enable_alt_bn128_syscall, enable_big_mod_exp_syscall,
enable_early_verification_of_account_modifications,
error_on_syscall_bpf_function_hash_collisions, libsecp256k1_0_5_upgrade_enabled,
limit_secp256k1_recovery_id, reject_callx_r10,
@ -186,6 +187,7 @@ pub fn create_loader<'a>(
};
let enable_alt_bn128_syscall = feature_set.is_active(&enable_alt_bn128_syscall::id());
let enable_big_mod_exp_syscall = feature_set.is_active(&enable_big_mod_exp_syscall::id());
let blake3_syscall_enabled = feature_set.is_active(&blake3_syscall_enabled::id());
let curve25519_syscall_enabled = feature_set.is_active(&curve25519_syscall_enabled::id());
let disable_fees_sysvar = feature_set.is_active(&disable_fees_sysvar::id());
@ -306,6 +308,14 @@ pub fn create_loader<'a>(
"sol_alt_bn128_group_op",
SyscallAltBn128::call,
)?;
// Big_mod_exp
register_feature_gated_function!(
result,
enable_big_mod_exp_syscall,
"sol_big_mod_exp",
SyscallBigModExp::call,
)?;
}
// Log data
@ -1718,6 +1728,80 @@ declare_syscall!(
}
);
declare_syscall!(
/// Big integer modular exponentiation
SyscallBigModExp,
fn inner_call(
invoke_context: &mut InvokeContext,
params: u64,
return_value: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
) -> Result<u64, EbpfError> {
let params = &translate_slice::<BigModExpParams>(
memory_mapping,
params,
1,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
)?
.get(0)
.ok_or(SyscallError::InvalidLength)?;
let input_len: u64 = std::cmp::max(params.base_len, params.exponent_len);
let input_len: u64 = std::cmp::max(input_len, params.modulus_len);
let budget = invoke_context.get_compute_budget();
consume_compute_meter(
invoke_context,
budget.syscall_base_cost.saturating_add(
input_len
.saturating_mul(input_len)
.saturating_div(budget.big_modular_exponentiation_cost),
),
)?;
let base = translate_slice::<u8>(
memory_mapping,
params.base as *const _ as *const u8 as u64,
params.base_len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
)?;
let exponent = translate_slice::<u8>(
memory_mapping,
params.exponent as *const _ as *const u8 as u64,
params.exponent_len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
)?;
let modulus = translate_slice::<u8>(
memory_mapping,
params.modulus as *const _ as *const u8 as u64,
params.modulus_len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
)?;
let value = big_mod_exp(base, exponent, modulus);
let return_value = translate_slice_mut::<u8>(
memory_mapping,
return_value,
params.modulus_len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
)?;
return_value.copy_from_slice(value.as_slice());
Ok(0)
}
);
#[cfg(test)]
mod tests {
#[allow(deprecated)]

View File

@ -4319,6 +4319,16 @@ dependencies = [
"solana-program 1.15.0",
]
[[package]]
name = "solana-bpf-rust-big-mod-exp"
version = "1.15.0"
dependencies = [
"array-bytes",
"serde",
"serde_json",
"solana-program 1.15.0",
]
[[package]]
name = "solana-bucket-map"
version = "1.15.0"
@ -4974,6 +4984,7 @@ dependencies = [
"libsecp256k1 0.6.0",
"log",
"memoffset",
"num-bigint 0.4.3",
"num-derive",
"num-traits",
"parking_lot 0.12.1",

View File

@ -52,6 +52,7 @@ members = [
"rust/128bit_dep",
"rust/alloc",
"rust/alt_bn128",
"rust/big_mod_exp",
"rust/call_depth",
"rust/caller_access",
"rust/curve25519",

View File

@ -61,6 +61,7 @@ fn main() {
"128bit",
"alloc",
"alt_bn128",
"big_mod_exp",
"call_depth",
"caller_access",
"curve25519",

View File

@ -0,0 +1,49 @@
/**
* @brief Big integer modular exponentiation Syscall test
*/
#include <solana_sdk.h>
extern uint64_t entrypoint(const uint8_t *input) {
struct BigModExpParam{
char* base;
size_t base_len;
char* exponent;
size_t exponent_len;
char* modulus;
size_t modulus_len;
} params;
uint8_t base[32] = {
0x98, 0x74, 0x23, 0x14, 0x72, 0x31, 0x74, 0x32, 0x84, 0x79, 0x23, 0x17, 0x43, 0x92, 0x87, 0x49,
0x18, 0x23, 0x74, 0x39, 0x28, 0x74, 0x92, 0x37, 0x49, 0x32, 0x87, 0x19, 0x37, 0x28, 0x97, 0x19
};
uint8_t exponent[32] = {
0x09, 0x48, 0x40, 0x39, 0x85, 0x40, 0x12, 0x32, 0x88, 0x94, 0x38, 0x57, 0x94, 0x75, 0x81, 0x23,
0x47, 0x23, 0x20, 0x99, 0x08, 0x00, 0x51, 0x35, 0x61, 0x65, 0x12, 0x61, 0x66, 0x26, 0x62, 0x22
};
uint8_t modulus[32] = {
0x25, 0x53, 0x23, 0x21, 0xa2, 0x14, 0x32, 0x14, 0x23, 0x12, 0x42, 0x12, 0x22, 0x22, 0x24, 0x22,
0x2b, 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24, 0x44
};
uint8_t expected[32] = {
0x22, 0x0e, 0xce, 0x1c, 0x42, 0x62, 0x4e, 0x98, 0xae, 0xe7, 0xeb, 0x86, 0x57, 0x8b, 0x2f, 0xe5,
0xc4, 0x85, 0x5d, 0xff, 0xac, 0xcb, 0x43, 0xcc, 0xbb, 0x70, 0x8a, 0x3a, 0xb3, 0x7f, 0x18, 0x4d
};
uint8_t result[32];
params.base = (char*) base;
params.base_len = sizeof(base);
params.exponent = (char*) exponent;
params.exponent_len = sizeof(exponent);
params.modulus = (char*) modulus;
params.modulus_len = sizeof(modulus);
uint64_t result_code = sol_big_mod_exp((uint8_t *) &params, result);
sol_assert(0 == result_code);
sol_assert(0 == sol_memcmp(result, expected, 32));
return SUCCESS;
}

View File

@ -0,0 +1,22 @@
[package]
name = "solana-bpf-rust-big-mod-exp"
version = "1.15.0"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-bpf-rust-big-mod-exp"
edition = "2021"
[dependencies]
array-bytes = "=1.4.1"
serde = { version = "1.0.112", features = ["derive"] }
serde_json = "1.0.56"
solana-program = { path = "../../../../sdk/program", version = "=1.15.0" }
[lib]
crate-type = ["cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@ -0,0 +1,93 @@
//! Big_mod_exp Syscall tests
extern crate solana_program;
use solana_program::{big_mod_exp::big_mod_exp, custom_panic_default, msg};
fn big_mod_exp_test() {
#[derive(serde::Deserialize)]
#[serde(rename_all = "PascalCase")]
struct TestCase {
base: String,
exponent: String,
modulus: String,
expected: String,
}
let test_data = r#"[
{
"Base": "1111111111111111111111111111111111111111111111111111111111111111",
"Exponent": "1111111111111111111111111111111111111111111111111111111111111111",
"Modulus": "111111111111111111111111111111111111111111111111111111111111110A",
"Expected": "0A7074864588D6847F33A168209E516F60005A0CEC3F33AAF70E8002FE964BCD"
},
{
"Base": "2222222222222222222222222222222222222222222222222222222222222222",
"Exponent": "2222222222222222222222222222222222222222222222222222222222222222",
"Modulus": "1111111111111111111111111111111111111111111111111111111111111111",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"Base": "3333333333333333333333333333333333333333333333333333333333333333",
"Exponent": "3333333333333333333333333333333333333333333333333333333333333333",
"Modulus": "2222222222222222222222222222222222222222222222222222222222222222",
"Expected": "1111111111111111111111111111111111111111111111111111111111111111"
},
{
"Base": "9874231472317432847923174392874918237439287492374932871937289719",
"Exponent": "0948403985401232889438579475812347232099080051356165126166266222",
"Modulus": "25532321a214321423124212222224222b242222222222222222222222222444",
"Expected": "220ECE1C42624E98AEE7EB86578B2FE5C4855DFFACCB43CCBB708A3AB37F184D"
},
{
"Base": "3494396663463663636363662632666565656456646566786786676786768766",
"Exponent": "2324324333246536456354655645656616169896565698987033121934984955",
"Modulus": "0218305479243590485092843590249879879842313131156656565565656566",
"Expected": "012F2865E8B9E79B645FCE3A9E04156483AE1F9833F6BFCF86FCA38FC2D5BEF0"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000005",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000002",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000007",
"Expected": "0000000000000000000000000000000000000000000000000000000000000004"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000064",
"Expected": "0000000000000000000000000000000000000000000000000000000000000019"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000000",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000001",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
}
]"#;
let test_cases: Vec<TestCase> = serde_json::from_str(test_data).unwrap();
test_cases.iter().for_each(|test| {
let base = array_bytes::hex2bytes_unchecked(&test.base);
let exponent = array_bytes::hex2bytes_unchecked(&test.exponent);
let modulus = array_bytes::hex2bytes_unchecked(&test.modulus);
let expected = array_bytes::hex2bytes_unchecked(&test.expected);
let result = big_mod_exp(base.as_slice(), exponent.as_slice(), modulus.as_slice());
assert_eq!(result, expected);
});
}
#[no_mangle]
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
msg!("big_mod_exp");
big_mod_exp_test();
0
}
custom_panic_default!();

View File

@ -0,0 +1,32 @@
#pragma once
/**
* @brief Solana big_mod_exp system call
**/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Big integer modular exponentiation
*
* @param bytes Pointer to BigModExpParam struct
* @param result 32 byte array to hold the result
* @return 0 if executed successfully
*/
/* DO NOT MODIFY THIS GENERATED FILE. INSTEAD CHANGE sdk/bpf/c/inc/sol/inc/big_mod_exp.inc AND RUN `cargo run --bin gen-headers` */
#ifndef SOL_SBFV2
uint64_t sol_big_mod_exp(const uint8_t *, uint8_t *);
#else
typedef uint64_t(*sol_big_mod_exp_pointer_type)(const uint8_t *, uint8_t *);
static uint64_t sol_big_mod_exp(const uint8_t * arg1, uint8_t * arg2) {
sol_big_mod_exp_pointer_type sol_big_mod_exp_pointer = (sol_big_mod_exp_pointer_type) 2014202901;
return sol_big_mod_exp_pointer(arg1, arg2);
}
#endif
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,23 @@
#pragma once
/**
* @brief Solana big_mod_exp system call
**/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Big integer modular exponentiation
*
* @param bytes Pointer to BigModExpParam struct
* @param result 32 byte array to hold the result
* @return 0 if executed successfully
*/
@SYSCALL uint64_t sol_big_mod_exp(const uint8_t *, uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -5,6 +5,7 @@
#include <sol/alt_bn128.h>
#include <sol/assert.h>
#include <sol/big_mod_exp.h>
#include <sol/blake3.h>
#include <sol/cpi.h>
#include <sol/deserialize.h>

View File

@ -47,6 +47,7 @@ curve25519-dalek = { version = "3.2.1", features = ["serde"] }
itertools = "0.10.5"
libc = { version = "0.2.126", features = ["extra_traits"] }
libsecp256k1 = "0.6.0"
num-bigint = "0.4.3"
rand = "0.7"
rand_chacha = { version = "0.2.2", default-features = true, features = ["simd", "std"] }
tiny-bip39 = "0.8.2"

View File

@ -0,0 +1,141 @@
#[repr(C)]
pub struct BigModExpParams {
pub base: *const u8,
pub base_len: u64,
pub exponent: *const u8,
pub exponent_len: u64,
pub modulus: *const u8,
pub modulus_len: u64,
}
/// Big integer modular exponentiation
pub fn big_mod_exp(base: &[u8], exponent: &[u8], modulus: &[u8]) -> Vec<u8> {
#[cfg(not(target_os = "solana"))]
{
use {
num_bigint::BigUint,
num_traits::{One, Zero},
};
let modulus_len = modulus.len();
let base = BigUint::from_bytes_be(base);
let exponent = BigUint::from_bytes_be(exponent);
let modulus = BigUint::from_bytes_be(modulus);
if modulus.is_zero() || modulus.is_one() {
return vec![0_u8; modulus_len];
}
let ret_int = base.modpow(&exponent, &modulus);
let ret_int = ret_int.to_bytes_be();
let mut return_value = vec![0_u8; modulus_len.saturating_sub(ret_int.len())];
return_value.extend(ret_int);
return_value
}
#[cfg(target_os = "solana")]
{
let mut return_value = vec![0_u8; modulus.len()];
let param = BigModExpParams {
base: base as *const _ as *const u8,
base_len: base.len() as u64,
exponent: exponent as *const _ as *const u8,
exponent_len: exponent.len() as u64,
modulus: modulus as *const _ as *const u8,
modulus_len: modulus.len() as u64,
};
unsafe {
crate::syscalls::sol_big_mod_exp(
&param as *const _ as *const u8,
return_value.as_mut_slice() as *mut _ as *mut u8,
)
};
return_value
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn big_mod_exp_test() {
#[derive(serde::Deserialize)]
#[serde(rename_all = "PascalCase")]
struct TestCase {
base: String,
exponent: String,
modulus: String,
expected: String,
}
let test_data = r#"[
{
"Base": "1111111111111111111111111111111111111111111111111111111111111111",
"Exponent": "1111111111111111111111111111111111111111111111111111111111111111",
"Modulus": "111111111111111111111111111111111111111111111111111111111111110A",
"Expected": "0A7074864588D6847F33A168209E516F60005A0CEC3F33AAF70E8002FE964BCD"
},
{
"Base": "2222222222222222222222222222222222222222222222222222222222222222",
"Exponent": "2222222222222222222222222222222222222222222222222222222222222222",
"Modulus": "1111111111111111111111111111111111111111111111111111111111111111",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"Base": "3333333333333333333333333333333333333333333333333333333333333333",
"Exponent": "3333333333333333333333333333333333333333333333333333333333333333",
"Modulus": "2222222222222222222222222222222222222222222222222222222222222222",
"Expected": "1111111111111111111111111111111111111111111111111111111111111111"
},
{
"Base": "9874231472317432847923174392874918237439287492374932871937289719",
"Exponent": "0948403985401232889438579475812347232099080051356165126166266222",
"Modulus": "25532321a214321423124212222224222b242222222222222222222222222444",
"Expected": "220ECE1C42624E98AEE7EB86578B2FE5C4855DFFACCB43CCBB708A3AB37F184D"
},
{
"Base": "3494396663463663636363662632666565656456646566786786676786768766",
"Exponent": "2324324333246536456354655645656616169896565698987033121934984955",
"Modulus": "0218305479243590485092843590249879879842313131156656565565656566",
"Expected": "012F2865E8B9E79B645FCE3A9E04156483AE1F9833F6BFCF86FCA38FC2D5BEF0"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000005",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000002",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000007",
"Expected": "0000000000000000000000000000000000000000000000000000000000000004"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000064",
"Expected": "0000000000000000000000000000000000000000000000000000000000000019"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000000",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"Base": "0000000000000000000000000000000000000000000000000000000000000019",
"Exponent": "0000000000000000000000000000000000000000000000000000000000000019",
"Modulus": "0000000000000000000000000000000000000000000000000000000000000001",
"Expected": "0000000000000000000000000000000000000000000000000000000000000000"
}
]"#;
let test_cases: Vec<TestCase> = serde_json::from_str(test_data).unwrap();
test_cases.iter().for_each(|test| {
let base = array_bytes::hex2bytes_unchecked(&test.base);
let exponent = array_bytes::hex2bytes_unchecked(&test.exponent);
let modulus = array_bytes::hex2bytes_unchecked(&test.modulus);
let expected = array_bytes::hex2bytes_unchecked(&test.expected);
let result = big_mod_exp(base.as_slice(), exponent.as_slice(), modulus.as_slice());
assert_eq!(result, expected);
});
}
}

View File

@ -478,6 +478,7 @@ pub mod account_info;
pub mod address_lookup_table_account;
pub mod alt_bn128;
pub(crate) mod atomic_u64;
pub mod big_mod_exp;
pub mod blake3;
pub mod borsh;
pub mod bpf_loader;

View File

@ -66,6 +66,7 @@ define_syscall!(fn sol_curve_group_op(curve_id: u64, group_op: u64, left_input_a
define_syscall!(fn sol_curve_multiscalar_mul(curve_id: u64, scalars_addr: *const u8, points_addr: *const u8, points_len: u64, result_point_addr: *mut u8) -> u64);
define_syscall!(fn sol_curve_pairing_map(curve_id: u64, point: *const u8, result: *mut u8) -> u64);
define_syscall!(fn sol_alt_bn128_group_op(group_op: u64, input: *const u8, input_size: u64, result: *mut u8) -> u64);
define_syscall!(fn sol_big_mod_exp(params: *const u8, result: *mut u8) -> u64);
#[cfg(target_feature = "static-syscalls")]
pub const fn sys_hash(name: &str) -> usize {

View File

@ -0,0 +1,32 @@
#pragma once
/**
* @brief Solana big_mod_exp system call
**/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Big integer modular exponentiation
*
* @param bytes Pointer to BigModExpParam struct
* @param result 32 byte array to hold the result
* @return 0 if executed successfully
*/
/* DO NOT MODIFY THIS GENERATED FILE. INSTEAD CHANGE sdk/sbf/c/inc/sol/inc/big_mod_exp.inc AND RUN `cargo run --bin gen-headers` */
#ifndef SOL_SBFV2
uint64_t sol_big_mod_exp(const uint8_t *, uint8_t *);
#else
typedef uint64_t(*sol_big_mod_exp_pointer_type)(const uint8_t *, uint8_t *);
static uint64_t sol_big_mod_exp(const uint8_t * arg1, uint8_t * arg2) {
sol_big_mod_exp_pointer_type sol_big_mod_exp_pointer = (sol_big_mod_exp_pointer_type) 2014202901;
return sol_big_mod_exp_pointer(arg1, arg2);
}
#endif
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,23 @@
#pragma once
/**
* @brief Solana big_mod_exp system call
**/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Big integer modular exponentiation
*
* @param bytes Pointer to BigModExpParam struct
* @param result 32 byte array to hold the result
* @return 0 if executed successfully
*/
@SYSCALL uint64_t sol_big_mod_exp(const uint8_t *, uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -4,6 +4,7 @@
*/
#include <sol/assert.h>
#include <sol/big_mod_exp.h>
#include <sol/blake3.h>
#include <sol/cpi.h>
#include <sol/deserialize.h>

View File

@ -586,6 +586,10 @@ pub mod update_hashes_per_tick {
solana_sdk::declare_id!("3uFHb9oKdGfgZGJK9EHaAXN4USvnQtAFC13Fh5gGFS5B");
}
pub mod enable_big_mod_exp_syscall {
solana_sdk::declare_id!("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXBGMDEXP");
}
lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@ -727,6 +731,7 @@ lazy_static! {
(keep_merkle_shreds::id(), "keep merkle shreds #29711"),
(move_serialized_len_ptr_in_cpi::id(), "cpi ignore serialized_len_ptr #29592"),
(update_hashes_per_tick::id(), "Update desired hashes per tick on epoch boundary"),
(enable_big_mod_exp_syscall::id(), "add big_mod_exp syscall #28503"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()

View File

@ -43,7 +43,7 @@ pub use signer::signers;
#[cfg(not(target_os = "solana"))]
pub use solana_program::program_stubs;
pub use solana_program::{
account_info, address_lookup_table_account, alt_bn128, blake3, borsh, bpf_loader,
account_info, address_lookup_table_account, alt_bn128, big_mod_exp, blake3, borsh, bpf_loader,
bpf_loader_deprecated, bpf_loader_upgradeable, clock, config, custom_heap_default,
custom_panic_default, debug_account_data, declare_deprecated_sysvar_id, declare_sysvar_id,
decode_error, ed25519_program, epoch_schedule, fee_calculator, impl_sysvar_get, incinerator,