diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index e2d9963efe..5c68084bb9 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -3927,6 +3927,14 @@ dependencies = [ "solana-program 1.11.0", ] +[[package]] +name = "solana-bpf-rust-curve25519" +version = "1.11.0" +dependencies = [ + "solana-program 1.11.0", + "solana-zk-token-sdk 1.11.0", +] + [[package]] name = "solana-bpf-rust-custom-heap" version = "1.11.0" diff --git a/programs/bpf/Cargo.toml b/programs/bpf/Cargo.toml index 943173422e..8c1b4f6efd 100644 --- a/programs/bpf/Cargo.toml +++ b/programs/bpf/Cargo.toml @@ -50,6 +50,7 @@ members = [ "rust/alloc", "rust/call_depth", "rust/caller_access", + "rust/curve25519", "rust/custom_heap", "rust/dep_crate", "rust/deprecated_loader", diff --git a/programs/bpf/build.rs b/programs/bpf/build.rs index f237b656c2..3a4ca6c348 100644 --- a/programs/bpf/build.rs +++ b/programs/bpf/build.rs @@ -62,6 +62,7 @@ fn main() { "alloc", "call_depth", "caller_access", + "curve25519", "custom_heap", "dep_crate", "deprecated_loader", diff --git a/programs/bpf/rust/curve25519/Cargo.toml b/programs/bpf/rust/curve25519/Cargo.toml new file mode 100644 index 0000000000..70ad87eb68 --- /dev/null +++ b/programs/bpf/rust/curve25519/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "solana-bpf-rust-curve25519" +version = "1.11.0" +description = "Solana BPF test program written in Rust" +authors = ["Solana Maintainers "] +repository = "https://github.com/solana-labs/solana" +license = "Apache-2.0" +homepage = "https://solana.com/" +documentation = "https://docs.rs/solana-bpf-rust-zktoken_crypto" +edition = "2018" + +[dependencies] +solana-program = { path = "../../../../sdk/program", version = "=1.11.0" } +solana-zk-token-sdk = { path = "../../../../zk-token-sdk", version = "=1.11.0" } + +[lib] +crate-type = ["cdylib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/programs/bpf/rust/curve25519/src/lib.rs b/programs/bpf/rust/curve25519/src/lib.rs new file mode 100644 index 0000000000..3f1e35ac4d --- /dev/null +++ b/programs/bpf/rust/curve25519/src/lib.rs @@ -0,0 +1,71 @@ +//! @brief curve25519 syscall tests + +extern crate solana_program; +use { + solana_program::{custom_heap_default, custom_panic_default, msg}, + solana_zk_token_sdk::curve25519::{edwards, ristretto, scalar}, +}; + +#[no_mangle] +pub extern "C" fn entrypoint(_input: *mut u8) -> u64 { + let scalar_one = scalar::PodScalar([ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + ]); + + let edwards_identity = edwards::PodEdwardsPoint([ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + ]); + + let edwards_generator = edwards::PodEdwardsPoint([ + 88, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + ]); + + msg!("validate_edwards"); + assert!(edwards::validate_edwards(&edwards_generator)); + + msg!("add_edwards"); + assert_eq!( + edwards_generator, + edwards::add_edwards(&edwards_generator, &edwards_identity).expect("add_edwards") + ); + + msg!("multiply_edwards"); + assert_eq!( + edwards_generator, + edwards::multiply_edwards(&scalar_one, &edwards_generator).expect("multiply_edwards") + ); + + let ristretto_identity = ristretto::PodRistrettoPoint([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + ]); + + let ristretto_generator = ristretto::PodRistrettoPoint([ + 226, 242, 174, 10, 106, 188, 78, 113, 168, 132, 169, 97, 197, 0, 81, 95, 88, 227, 11, 106, + 165, 130, 221, 141, 182, 166, 89, 69, 224, 141, 45, 118, + ]); + + msg!("validate_ristretto"); + assert!(ristretto::validate_ristretto(&ristretto_generator)); + + msg!("add_ristretto"); + assert_eq!( + ristretto_generator, + ristretto::add_ristretto(&ristretto_generator, &ristretto_identity).expect("add_ristretto") + ); + + msg!("multiply_ristretto"); + assert_eq!( + ristretto_generator, + ristretto::multiply_ristretto(&scalar_one, &ristretto_generator) + .expect("multiply_ristretto") + ); + + 0 +} + +custom_heap_default!(); +custom_panic_default!(); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 6bfbe64018..20327763c3 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -500,6 +500,7 @@ fn test_program_bpf_sanity() { programs.extend_from_slice(&[ ("solana_bpf_rust_128bit", true), ("solana_bpf_rust_alloc", true), + ("solana_bpf_rust_curve25519", true), ("solana_bpf_rust_custom_heap", true), ("solana_bpf_rust_dep_crate", true), ("solana_bpf_rust_external_spend", false), diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 30d54e1046..3a933ee2fb 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -243,14 +243,14 @@ pub fn register_syscalls( register_feature_gated_syscall!( syscall_registry, curve25519_syscall_enabled, - b"sol_curve25519_point_validation", + b"sol_curve_validate_point", SyscallCurvePointValidation::init, SyscallCurvePointValidation::call, )?; register_feature_gated_syscall!( syscall_registry, curve25519_syscall_enabled, - b"sol_curve25519_point_validation", + b"sol_curve_group_op", SyscallCurveGroupOps::init, SyscallCurveGroupOps::call, )?; diff --git a/sdk/bpf/dependencies/sbf-tools b/sdk/bpf/dependencies/sbf-tools new file mode 120000 index 0000000000..3d0a67617a --- /dev/null +++ b/sdk/bpf/dependencies/sbf-tools @@ -0,0 +1 @@ +/Users/samkim/.cache/solana/v1.27/sbf-tools \ No newline at end of file diff --git a/sdk/program/src/syscalls.rs b/sdk/program/src/syscalls.rs index 1aed6e8051..aff4710ae9 100644 --- a/sdk/program/src/syscalls.rs +++ b/sdk/program/src/syscalls.rs @@ -65,7 +65,7 @@ define_syscall!(fn sol_log_data(data: *const u8, data_len: u64)); define_syscall!(fn sol_get_processed_sibling_instruction(index: u64, meta: *mut ProcessedSiblingInstruction, program_id: *mut Pubkey, data: *mut u8, accounts: *mut AccountMeta) -> u64); define_syscall!(fn sol_get_stack_height() -> u64); define_syscall!(fn sol_curve_validate_point(curve_id: u64, point: *const u8, result: *mut u8) -> u64); -define_syscall!(fn sol_curve_op(curve_id: u64, op_id: u64, left_point: *const u8, right_point: *const u8, result: *mut u8) -> u64); +define_syscall!(fn sol_curve_group_op(curve_id: u64, op_id: u64, left_point: *const u8, right_point: *const u8, result: *mut u8) -> u64); define_syscall!(fn sol_curve_multiscalar_mul(curve_id: u64, scalars: *const u8, points: *const u8, result: *mut u8) -> u64); define_syscall!(fn sol_curve_pairing_map(curve_id: u64, point: *const u8, result: *mut u8) -> u64); diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index e84651545e..000c7e5d51 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -472,6 +472,7 @@ lazy_static! { (stake_merge_with_unmatched_credits_observed::id(), "allow merging active stakes with unmatched credits_observed #18985"), (gate_large_block::id(), "validator checks block cost against max limit in realtime, reject if exceeds."), (zk_token_sdk_enabled::id(), "enable Zk Token proof program and syscalls"), + (curve25519_syscall_enabled::id(), "enable curve25519 syscalls"), (versioned_tx_message_enabled::id(), "enable versioned transaction message processing"), (libsecp256k1_fail_on_bad_count::id(), "fail libsec256k1_verify if count appears wrong"), (instructions_sysvar_owned_by_sysvar::id(), "fix owner for instructions sysvar"), diff --git a/zk-token-sdk/src/curve25519/curve_syscall_traits.rs b/zk-token-sdk/src/curve25519/curve_syscall_traits.rs index 4112de5d09..2e4fe18c5d 100644 --- a/zk-token-sdk/src/curve25519/curve_syscall_traits.rs +++ b/zk-token-sdk/src/curve25519/curve_syscall_traits.rs @@ -9,6 +9,12 @@ //! zk-token-sdk or curve25519. It should be moved to a more general location in the future. //! +// Functions are organized by the curve traits, which can be instantiated by multiple curve +// representations. The functions take in a `curve_id` (e.g. `CURVE25519_EDWARDS`) and should run +// the associated functions in the appropriate trait instantiation. The `curve_op` function +// additionally takes in an `op_id` (e.g. `ADD`) that controls which associated functions to run in +// `GroupOperations`. + pub trait PointValidation { type Point; @@ -77,13 +83,3 @@ pub const CURVE25519_RISTRETTO: u64 = 1; pub const ADD: u64 = 0; pub const SUB: u64 = 1; pub const MUL: u64 = 2; - -// Functions are organized by the curve traits, which can be instantiated by multiple curve -// representations. The functions take in a `curve_id` (e.g. `CURVE25519_EDWARDS`) and should run -// the associated functions in the appropriate trait instantiation. The `curve_op` function -// additionally takes in an `op_id` (e.g. `ADD`) that controls which associated functions to run in -// `GroupOperations`. -#[cfg(target_os = "solana")] -pub use solana_program::syscalls::{ - sol_curve_multiscalar_mul, sol_curve_op, sol_curve_pairing_map, sol_curve_validate_point, -}; diff --git a/zk-token-sdk/src/curve25519/edwards.rs b/zk-token-sdk/src/curve25519/edwards.rs index 7f13149b4a..8cd7a4abd4 100644 --- a/zk-token-sdk/src/curve25519/edwards.rs +++ b/zk-token-sdk/src/curve25519/edwards.rs @@ -129,15 +129,16 @@ mod target_arch { mod target_arch { use { super::*, - crate::curve25519::curve_syscall_traits::{ - sol_curve_op, sol_curve_validate_point, ADD, CURVE25519_EDWARDS, MUL, SUB, + crate::curve25519::{ + curve_syscall_traits::{ADD, CURVE25519_EDWARDS, MUL, SUB}, + scalar::PodScalar, }, }; pub fn validate_edwards(point: &PodEdwardsPoint) -> bool { let mut validate_result = 0u8; let result = unsafe { - sol_curve_validate_point( + solana_program::syscalls::sol_curve_validate_point( CURVE25519_EDWARDS, &point.0 as *const u8, &mut validate_result, @@ -152,7 +153,7 @@ mod target_arch { ) -> Option { let mut result_point = PodEdwardsPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_EDWARDS, ADD, &left_point.0 as *const u8, @@ -174,7 +175,7 @@ mod target_arch { ) -> Option { let mut result_point = PodEdwardsPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_EDWARDS, SUB, &left_point.0 as *const u8, @@ -191,16 +192,16 @@ mod target_arch { } pub fn multiply_edwards( - left_point: &PodEdwardsPoint, - right_point: &PodEdwardsPoint, + scalar: &PodScalar, + point: &PodEdwardsPoint, ) -> Option { let mut result_point = PodEdwardsPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_EDWARDS, MUL, - &left_point.0 as *const u8, - &right_point.0 as *const u8, + &scalar.0 as *const u8, + &point.0 as *const u8, &mut result_point.0 as *mut u8, ) }; diff --git a/zk-token-sdk/src/curve25519/ristretto.rs b/zk-token-sdk/src/curve25519/ristretto.rs index 7ad6a8b27a..612f9309bf 100644 --- a/zk-token-sdk/src/curve25519/ristretto.rs +++ b/zk-token-sdk/src/curve25519/ristretto.rs @@ -130,15 +130,16 @@ mod target_arch { mod target_arch { use { super::*, - crate::curve25519::curve_syscall_traits::{ - sol_curve_op, sol_curve_validate_point, ADD, CURVE25519_RISTRETTO, MUL, SUB, + crate::curve25519::{ + curve_syscall_traits::{ADD, CURVE25519_RISTRETTO, MUL, SUB}, + scalar::PodScalar, }, }; pub fn validate_ristretto(point: &PodRistrettoPoint) -> bool { let mut validate_result = 0u8; let result = unsafe { - sol_curve_validate_point( + solana_program::syscalls::sol_curve_validate_point( CURVE25519_RISTRETTO, &point.0 as *const u8, &mut validate_result, @@ -154,7 +155,7 @@ mod target_arch { ) -> Option { let mut result_point = PodRistrettoPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_RISTRETTO, ADD, &left_point.0 as *const u8, @@ -176,7 +177,7 @@ mod target_arch { ) -> Option { let mut result_point = PodRistrettoPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_RISTRETTO, SUB, &left_point.0 as *const u8, @@ -193,16 +194,16 @@ mod target_arch { } pub fn multiply_ristretto( - left_point: &PodRistrettoPoint, - right_point: &PodRistrettoPoint, + scalar: &PodScalar, + point: &PodRistrettoPoint, ) -> Option { let mut result_point = PodRistrettoPoint::zeroed(); let result = unsafe { - sol_curve_op( + solana_program::syscalls::sol_curve_group_op( CURVE25519_RISTRETTO, MUL, - &left_point.0 as *const u8, - &right_point.0 as *const u8, + &scalar.0 as *const u8, + &point.0 as *const u8, &mut result_point.0 as *mut u8, ) };