From 5bdb82c3c2c8d2719d8293dbc8305c886875765b Mon Sep 17 00:00:00 2001 From: LStan Date: Mon, 8 Sep 2025 16:37:38 +0700 Subject: [PATCH 01/11] add alt_bn128 syscalls --- sdk/pinocchio/src/curves/bn254/compression.rs | 214 ++++++++++++++++++ sdk/pinocchio/src/curves/bn254/group_op.rs | 189 ++++++++++++++++ sdk/pinocchio/src/curves/bn254/mod.rs | 11 + sdk/pinocchio/src/curves/mod.rs | 3 + sdk/pinocchio/src/lib.rs | 1 + 5 files changed, 418 insertions(+) create mode 100644 sdk/pinocchio/src/curves/bn254/compression.rs create mode 100644 sdk/pinocchio/src/curves/bn254/group_op.rs create mode 100644 sdk/pinocchio/src/curves/bn254/mod.rs create mode 100644 sdk/pinocchio/src/curves/mod.rs diff --git a/sdk/pinocchio/src/curves/bn254/compression.rs b/sdk/pinocchio/src/curves/bn254/compression.rs new file mode 100644 index 00000000..d5a08c52 --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/compression.rs @@ -0,0 +1,214 @@ +//! Compression/decompression of points on the BN254 curve. + +use super::{ALT_BN128_G1_SIZE, ALT_BN128_G2_SIZE}; +use crate::program_error::ProgramError; + +#[cfg(target_os = "solana")] +use crate::syscalls::sol_alt_bn128_compression; + +// compression sizes +pub const ALT_BN128_G1_COMPRESSED_SIZE: usize = ALT_BN128_G1_SIZE / 2; // 32 +pub const ALT_BN128_G2_COMPRESSED_SIZE: usize = ALT_BN128_G2_SIZE / 2; // 64 + +// compression operations +const ALT_BN128_G1_COMPRESS: u64 = 0; +const ALT_BN128_G1_DECOMPRESS: u64 = 1; +const ALT_BN128_G2_COMPRESS: u64 = 2; +const ALT_BN128_G2_DECOMPRESS: u64 = 3; + +/// Compress a G1 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A G1 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the compressed G1 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid G1 point. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g1_compress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G1_COMPRESSED_SIZE], ProgramError> { + alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) +} + +/// Compress a G1 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A G1 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the compressed G1 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid G1 point. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +pub fn checked_alt_bn128_g1_compress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G1_COMPRESSED_SIZE], ProgramError> { + if input.len() != ALT_BN128_G1_SIZE { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) +} + +/// Decompress a G1 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A compressed G1 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the decompressed G1 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid compressed G1 point. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g1_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G1_SIZE], ProgramError> { + alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) +} + +/// Decompress a G1 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A compressed G1 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the decompressed G1 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid compressed G1 point. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +pub fn checked_alt_bn128_g1_decompress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G1_SIZE], ProgramError> { + if input.len() != ALT_BN128_G1_COMPRESSED_SIZE { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) +} + +/// Compress a G2 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A G2 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the compressed G2 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid G2 point. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g2_compress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G2_COMPRESSED_SIZE], ProgramError> { + alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) +} + +/// Compress a G2 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A G2 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the compressed G2 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid G2 point. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +pub fn checked_alt_bn128_g2_compress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G2_COMPRESSED_SIZE], ProgramError> { + if input.len() != ALT_BN128_G2_SIZE { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) +} + +/// Decompress a G2 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A compressed G2 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the decompressed G2 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid compressed G2 point. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g2_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G2_SIZE], ProgramError> { + alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) +} + +/// Decompress a G2 point on the BN254 curve. +/// +/// # Arguments +/// +/// * `input` - A compressed G2 point in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the decompressed G2 point in big-endian (EIP-197) encoding, +/// or an error if the input is not a valid compressed G2 point. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +pub fn checked_alt_bn128_g2_decompress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G2_SIZE], ProgramError> { + if input.len() != ALT_BN128_G2_COMPRESSED_SIZE { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) +} + +#[inline] +fn alt_bn128_compression( + input: &[u8], + op: u64, +) -> Result<[u8; OUTPUT_DATA_LEN], ProgramError> { + // Call via a system call to perform the calculation + #[cfg(target_os = "solana")] + { + let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_LEN]>::uninit(); + + let result = unsafe { + sol_alt_bn128_compression( + op, + input as *const _ as *const u8, + input.len() as u64, + bytes.as_mut_ptr() as *mut u8, + ) + }; + + match result { + // SAFETY: The syscall has initialized the bytes. + crate::SUCCESS => Ok(unsafe { bytes.assume_init() }), + _ => Err(ProgramError::InvalidArgument), + } + } + + #[cfg(not(target_os = "solana"))] + { + core::hint::black_box((input, op)); + panic!("alt_bn128_compression is only available on target `solana`") + } +} diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs new file mode 100644 index 00000000..d34a62f4 --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/group_op.rs @@ -0,0 +1,189 @@ +//! Group operations on the BN254 curve. + +use super::{ALT_BN128_FIELD_SIZE, ALT_BN128_G1_SIZE, ALT_BN128_G2_SIZE}; +use crate::program_error::ProgramError; + +#[cfg(target_os = "solana")] +use crate::syscalls::sol_alt_bn128_group_op; + +/// Input length for the add operation. +pub const ALT_BN128_ADDITION_INPUT_LEN: usize = ALT_BN128_G1_SIZE * 2; // 128 + +/// Input length for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_INPUT_LEN: usize = ALT_BN128_G1_SIZE + ALT_BN128_FIELD_SIZE; // 96 + +/// Pair element length. +pub const ALT_BN128_PAIRING_ELEMENT_LEN: usize = ALT_BN128_G1_SIZE + ALT_BN128_G2_SIZE; // 192 + +/// Output length for the add operation. +pub const ALT_BN128_ADDITION_OUTPUT_LEN: usize = ALT_BN128_G1_SIZE; // 64 + +/// Output length for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_OUTPUT_LEN: usize = ALT_BN128_G1_SIZE; // 64 + +const ALT_BN128_ADD: u64 = 0; +#[allow(dead_code)] +const ALT_BN128_SUB: u64 = 1; // not implemented in the syscall +const ALT_BN128_MUL: u64 = 2; +const ALT_BN128_PAIRING: u64 = 3; + +/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, +/// or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_addition( + input: &[u8], +) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_LEN], ProgramError> { + alt_bn128_group_op(input, ALT_BN128_ADD) +} + +/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, +/// or an error if the input is invalid. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +#[inline(always)] +pub fn checked_alt_bn128_addition( + input: &[u8], +) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_LEN], ProgramError> { + if input.len() > ALT_BN128_ADDITION_INPUT_LEN { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_group_op(input, ALT_BN128_ADD) +} + +/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A G1 point in big-endian (EIP-197) encoding, +/// followed by a scalar in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the multiplication in big-endian (EIP-197) +/// encoding, or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_multiplication( + input: &[u8], +) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_LEN], ProgramError> { + alt_bn128_group_op(input, ALT_BN128_MUL) +} + +/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A G1 point in big-endian (EIP-197) encoding, +/// followed by a scalar in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the multiplication in big-endian (EIP-197) +/// encoding, or an error if the input is invalid. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +#[inline(always)] +pub fn checked_alt_bn128_multiplication( + input: &[u8], +) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_LEN], ProgramError> { + if input.len() > ALT_BN128_MULTIPLICATION_INPUT_LEN { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_group_op(input, ALT_BN128_MUL) +} + +/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// Currently, if the length is invalid, it will not return an error; instead it will use only +/// multiples of [`ALT_BN128_PAIRING_ELEMENT_LEN`] bytes and discard the rest. +/// After SIMD-0334 is implemented, it will return an error if the length is invalid, +/// incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_pairing(input: &[u8]) -> Result { + alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING).map(|data| data[31]) +} + +/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. +/// +/// Note: This function checks if the input has the correct length, +/// returning an error without incurring the cost of the syscall. +#[inline(always)] +pub fn checked_alt_bn128_pairing(input: &[u8]) -> Result { + if input.len() % ALT_BN128_PAIRING_ELEMENT_LEN != 0 { + return Err(ProgramError::InvalidArgument); + } + alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING).map(|data| data[31]) +} + +#[inline] +fn alt_bn128_group_op( + input: &[u8], + op: u64, +) -> Result<[u8; OUTPUT_DATA_LEN], ProgramError> { + // Call via a system call to perform the calculation + #[cfg(target_os = "solana")] + { + let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_LEN]>::uninit(); + + let result = unsafe { + sol_alt_bn128_group_op( + op, + input as *const _ as *const u8, + input.len() as u64, + bytes.as_mut_ptr() as *mut u8, + ) + }; + + match result { + // SAFETY: The syscall has initialized the bytes. + crate::SUCCESS => Ok(unsafe { bytes.assume_init() }), + _ => Err(ProgramError::InvalidArgument), + } + } + + #[cfg(not(target_os = "solana"))] + { + core::hint::black_box((input, op)); + panic!("alt_bn128_group_op is only available on target `solana`") + } +} diff --git a/sdk/pinocchio/src/curves/bn254/mod.rs b/sdk/pinocchio/src/curves/bn254/mod.rs new file mode 100644 index 00000000..383f5016 --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/mod.rs @@ -0,0 +1,11 @@ +//! BN254 curve operations + +pub mod compression; +pub mod group_op; + +pub use compression::*; +pub use group_op::*; + +pub const ALT_BN128_FIELD_SIZE: usize = 32; +pub const ALT_BN128_G1_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; // x, y each 32 byte +pub const ALT_BN128_G2_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; // x=(x0,x1), y=(y0,y1) each 32 byte diff --git a/sdk/pinocchio/src/curves/mod.rs b/sdk/pinocchio/src/curves/mod.rs new file mode 100644 index 00000000..08ea7879 --- /dev/null +++ b/sdk/pinocchio/src/curves/mod.rs @@ -0,0 +1,3 @@ +//! Functions for working with elliptic curves. + +pub mod bn254; diff --git a/sdk/pinocchio/src/lib.rs b/sdk/pinocchio/src/lib.rs index b4ae9098..de54cc9b 100644 --- a/sdk/pinocchio/src/lib.rs +++ b/sdk/pinocchio/src/lib.rs @@ -225,6 +225,7 @@ extern crate std; pub mod account_info; pub mod cpi; +pub mod curves; pub mod entrypoint; pub mod instruction; pub mod log; From 257db60f9e1883e57776ed30a79adcacc22d4495 Mon Sep 17 00:00:00 2001 From: LStan Date: Tue, 9 Sep 2025 02:20:59 +0700 Subject: [PATCH 02/11] update solana.dic --- scripts/setup/solana.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/setup/solana.dic b/scripts/setup/solana.dic index f7ba5508..a8940bb5 100644 --- a/scripts/setup/solana.dic +++ b/scripts/setup/solana.dic @@ -70,3 +70,6 @@ mainnet getters PRNG middleware +BN254 +G1 +G2 From 5bffbcb76c3dbe6739a5dfc625c75bb0d4c5aca3 Mon Sep 17 00:00:00 2001 From: LStan Date: Wed, 10 Sep 2025 19:46:33 +0700 Subject: [PATCH 03/11] comments --- sdk/pinocchio/src/curves/bn254/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/mod.rs b/sdk/pinocchio/src/curves/bn254/mod.rs index 383f5016..765bd5c6 100644 --- a/sdk/pinocchio/src/curves/bn254/mod.rs +++ b/sdk/pinocchio/src/curves/bn254/mod.rs @@ -6,6 +6,9 @@ pub mod group_op; pub use compression::*; pub use group_op::*; +/// Size of the EC point field, in bytes. pub const ALT_BN128_FIELD_SIZE: usize = 32; -pub const ALT_BN128_G1_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; // x, y each 32 byte -pub const ALT_BN128_G2_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; // x=(x0,x1), y=(y0,y1) each 32 byte +/// A group element in G1 consists of two field elements `(x, y)`. +pub const ALT_BN128_G1_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; +/// Elements in G2 is represented by 2 field-extension elements `(x, y)`. +pub const ALT_BN128_G2_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; From 6f1d04f683d05dbd59f36751966782890927bc9e Mon Sep 17 00:00:00 2001 From: LStan Date: Wed, 17 Sep 2025 16:03:38 +0700 Subject: [PATCH 04/11] rename constants --- sdk/pinocchio/src/curves/bn254/compression.rs | 34 +++++++++++-------- sdk/pinocchio/src/curves/bn254/group_op.rs | 13 +++---- sdk/pinocchio/src/curves/bn254/mod.rs | 4 +-- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/compression.rs b/sdk/pinocchio/src/curves/bn254/compression.rs index d5a08c52..f631452d 100644 --- a/sdk/pinocchio/src/curves/bn254/compression.rs +++ b/sdk/pinocchio/src/curves/bn254/compression.rs @@ -1,14 +1,14 @@ //! Compression/decompression of points on the BN254 curve. -use super::{ALT_BN128_G1_SIZE, ALT_BN128_G2_SIZE}; +use super::{ALT_BN128_G1_POINT_SIZE, ALT_BN128_G2_POINT_SIZE}; use crate::program_error::ProgramError; #[cfg(target_os = "solana")] use crate::syscalls::sol_alt_bn128_compression; // compression sizes -pub const ALT_BN128_G1_COMPRESSED_SIZE: usize = ALT_BN128_G1_SIZE / 2; // 32 -pub const ALT_BN128_G2_COMPRESSED_SIZE: usize = ALT_BN128_G2_SIZE / 2; // 64 +pub const ALT_BN128_G1_COMPRESSED_POINT_SIZE: usize = ALT_BN128_G1_POINT_SIZE / 2; // 32 +pub const ALT_BN128_G2_COMPRESSED_POINT_SIZE: usize = ALT_BN128_G2_POINT_SIZE / 2; // 64 // compression operations const ALT_BN128_G1_COMPRESS: u64 = 0; @@ -32,7 +32,7 @@ const ALT_BN128_G2_DECOMPRESS: u64 = 3; #[inline(always)] pub fn alt_bn128_g1_compress( input: &[u8], -) -> Result<[u8; ALT_BN128_G1_COMPRESSED_SIZE], ProgramError> { +) -> Result<[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) } @@ -51,8 +51,8 @@ pub fn alt_bn128_g1_compress( /// returning an error without incurring the cost of the syscall. pub fn checked_alt_bn128_g1_compress( input: &[u8], -) -> Result<[u8; ALT_BN128_G1_COMPRESSED_SIZE], ProgramError> { - if input.len() != ALT_BN128_G1_SIZE { +) -> Result<[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ProgramError> { + if input.len() != ALT_BN128_G1_POINT_SIZE { return Err(ProgramError::InvalidArgument); } alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) @@ -72,7 +72,9 @@ pub fn checked_alt_bn128_g1_compress( /// Note: This function does **not** check if the input has the correct length. /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_g1_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G1_SIZE], ProgramError> { +pub fn alt_bn128_g1_decompress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G1_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) } @@ -91,8 +93,8 @@ pub fn alt_bn128_g1_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G1_SIZE], /// returning an error without incurring the cost of the syscall. pub fn checked_alt_bn128_g1_decompress( input: &[u8], -) -> Result<[u8; ALT_BN128_G1_SIZE], ProgramError> { - if input.len() != ALT_BN128_G1_COMPRESSED_SIZE { +) -> Result<[u8; ALT_BN128_G1_POINT_SIZE], ProgramError> { + if input.len() != ALT_BN128_G1_COMPRESSED_POINT_SIZE { return Err(ProgramError::InvalidArgument); } alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) @@ -114,7 +116,7 @@ pub fn checked_alt_bn128_g1_decompress( #[inline(always)] pub fn alt_bn128_g2_compress( input: &[u8], -) -> Result<[u8; ALT_BN128_G2_COMPRESSED_SIZE], ProgramError> { +) -> Result<[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) } @@ -133,8 +135,8 @@ pub fn alt_bn128_g2_compress( /// returning an error without incurring the cost of the syscall. pub fn checked_alt_bn128_g2_compress( input: &[u8], -) -> Result<[u8; ALT_BN128_G2_COMPRESSED_SIZE], ProgramError> { - if input.len() != ALT_BN128_G2_SIZE { +) -> Result<[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ProgramError> { + if input.len() != ALT_BN128_G2_POINT_SIZE { return Err(ProgramError::InvalidArgument); } alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) @@ -154,7 +156,9 @@ pub fn checked_alt_bn128_g2_compress( /// Note: This function does **not** check if the input has the correct length. /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_g2_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G2_SIZE], ProgramError> { +pub fn alt_bn128_g2_decompress( + input: &[u8], +) -> Result<[u8; ALT_BN128_G2_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) } @@ -173,8 +177,8 @@ pub fn alt_bn128_g2_decompress(input: &[u8]) -> Result<[u8; ALT_BN128_G2_SIZE], /// returning an error without incurring the cost of the syscall. pub fn checked_alt_bn128_g2_decompress( input: &[u8], -) -> Result<[u8; ALT_BN128_G2_SIZE], ProgramError> { - if input.len() != ALT_BN128_G2_COMPRESSED_SIZE { +) -> Result<[u8; ALT_BN128_G2_POINT_SIZE], ProgramError> { + if input.len() != ALT_BN128_G2_COMPRESSED_POINT_SIZE { return Err(ProgramError::InvalidArgument); } alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs index d34a62f4..3e99e299 100644 --- a/sdk/pinocchio/src/curves/bn254/group_op.rs +++ b/sdk/pinocchio/src/curves/bn254/group_op.rs @@ -1,25 +1,26 @@ //! Group operations on the BN254 curve. -use super::{ALT_BN128_FIELD_SIZE, ALT_BN128_G1_SIZE, ALT_BN128_G2_SIZE}; +use super::{ALT_BN128_FIELD_SIZE, ALT_BN128_G1_POINT_SIZE, ALT_BN128_G2_POINT_SIZE}; use crate::program_error::ProgramError; #[cfg(target_os = "solana")] use crate::syscalls::sol_alt_bn128_group_op; /// Input length for the add operation. -pub const ALT_BN128_ADDITION_INPUT_LEN: usize = ALT_BN128_G1_SIZE * 2; // 128 +pub const ALT_BN128_ADDITION_INPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128 /// Input length for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_INPUT_LEN: usize = ALT_BN128_G1_SIZE + ALT_BN128_FIELD_SIZE; // 96 +pub const ALT_BN128_MULTIPLICATION_INPUT_LEN: usize = + ALT_BN128_G1_POINT_SIZE + ALT_BN128_FIELD_SIZE; // 96 /// Pair element length. -pub const ALT_BN128_PAIRING_ELEMENT_LEN: usize = ALT_BN128_G1_SIZE + ALT_BN128_G2_SIZE; // 192 +pub const ALT_BN128_PAIRING_ELEMENT_LEN: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192 /// Output length for the add operation. -pub const ALT_BN128_ADDITION_OUTPUT_LEN: usize = ALT_BN128_G1_SIZE; // 64 +pub const ALT_BN128_ADDITION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 /// Output length for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_OUTPUT_LEN: usize = ALT_BN128_G1_SIZE; // 64 +pub const ALT_BN128_MULTIPLICATION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 const ALT_BN128_ADD: u64 = 0; #[allow(dead_code)] diff --git a/sdk/pinocchio/src/curves/bn254/mod.rs b/sdk/pinocchio/src/curves/bn254/mod.rs index 765bd5c6..481a4df0 100644 --- a/sdk/pinocchio/src/curves/bn254/mod.rs +++ b/sdk/pinocchio/src/curves/bn254/mod.rs @@ -9,6 +9,6 @@ pub use group_op::*; /// Size of the EC point field, in bytes. pub const ALT_BN128_FIELD_SIZE: usize = 32; /// A group element in G1 consists of two field elements `(x, y)`. -pub const ALT_BN128_G1_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; +pub const ALT_BN128_G1_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; /// Elements in G2 is represented by 2 field-extension elements `(x, y)`. -pub const ALT_BN128_G2_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; +pub const ALT_BN128_G2_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; From b11958160902c474bc2308c264a81ab87fcf18dd Mon Sep 17 00:00:00 2001 From: LStan Date: Wed, 17 Sep 2025 16:31:46 +0700 Subject: [PATCH 05/11] remove checked functions --- sdk/pinocchio/src/curves/bn254/compression.rs | 108 +----------------- sdk/pinocchio/src/curves/bn254/group_op.rs | 67 ----------- 2 files changed, 4 insertions(+), 171 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/compression.rs b/sdk/pinocchio/src/curves/bn254/compression.rs index f631452d..2550e837 100644 --- a/sdk/pinocchio/src/curves/bn254/compression.rs +++ b/sdk/pinocchio/src/curves/bn254/compression.rs @@ -26,38 +26,13 @@ const ALT_BN128_G2_DECOMPRESS: u64 = 3; /// /// A `Result` containing the compressed G1 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid G1 point. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_compress( - input: &[u8], + input: &[u8; ALT_BN128_G1_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) } -/// Compress a G1 point on the BN254 curve. -/// -/// # Arguments -/// -/// * `input` - A G1 point in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the compressed G1 point in big-endian (EIP-197) encoding, -/// or an error if the input is not a valid G1 point. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -pub fn checked_alt_bn128_g1_compress( - input: &[u8], -) -> Result<[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ProgramError> { - if input.len() != ALT_BN128_G1_POINT_SIZE { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) -} - /// Decompress a G1 point on the BN254 curve. /// /// # Arguments @@ -68,38 +43,13 @@ pub fn checked_alt_bn128_g1_compress( /// /// A `Result` containing the decompressed G1 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid compressed G1 point. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_decompress( - input: &[u8], + input: &[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G1_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) } -/// Decompress a G1 point on the BN254 curve. -/// -/// # Arguments -/// -/// * `input` - A compressed G1 point in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the decompressed G1 point in big-endian (EIP-197) encoding, -/// or an error if the input is not a valid compressed G1 point. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -pub fn checked_alt_bn128_g1_decompress( - input: &[u8], -) -> Result<[u8; ALT_BN128_G1_POINT_SIZE], ProgramError> { - if input.len() != ALT_BN128_G1_COMPRESSED_POINT_SIZE { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) -} - /// Compress a G2 point on the BN254 curve. /// /// # Arguments @@ -110,38 +60,13 @@ pub fn checked_alt_bn128_g1_decompress( /// /// A `Result` containing the compressed G2 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid G2 point. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g2_compress( - input: &[u8], + input: &[u8; ALT_BN128_G2_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) } -/// Compress a G2 point on the BN254 curve. -/// -/// # Arguments -/// -/// * `input` - A G2 point in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the compressed G2 point in big-endian (EIP-197) encoding, -/// or an error if the input is not a valid G2 point. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -pub fn checked_alt_bn128_g2_compress( - input: &[u8], -) -> Result<[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ProgramError> { - if input.len() != ALT_BN128_G2_POINT_SIZE { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) -} - /// Decompress a G2 point on the BN254 curve. /// /// # Arguments @@ -152,38 +77,13 @@ pub fn checked_alt_bn128_g2_compress( /// /// A `Result` containing the decompressed G2 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid compressed G2 point. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g2_decompress( - input: &[u8], + input: &[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G2_POINT_SIZE], ProgramError> { alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) } -/// Decompress a G2 point on the BN254 curve. -/// -/// # Arguments -/// -/// * `input` - A compressed G2 point in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the decompressed G2 point in big-endian (EIP-197) encoding, -/// or an error if the input is not a valid compressed G2 point. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -pub fn checked_alt_bn128_g2_decompress( - input: &[u8], -) -> Result<[u8; ALT_BN128_G2_POINT_SIZE], ProgramError> { - if input.len() != ALT_BN128_G2_COMPRESSED_POINT_SIZE { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) -} - #[inline] fn alt_bn128_compression( input: &[u8], diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs index 3e99e299..cc639c5c 100644 --- a/sdk/pinocchio/src/curves/bn254/group_op.rs +++ b/sdk/pinocchio/src/curves/bn254/group_op.rs @@ -48,29 +48,6 @@ pub fn alt_bn128_addition( alt_bn128_group_op(input, ALT_BN128_ADD) } -/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, -/// or an error if the input is invalid. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -#[inline(always)] -pub fn checked_alt_bn128_addition( - input: &[u8], -) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_LEN], ProgramError> { - if input.len() > ALT_BN128_ADDITION_INPUT_LEN { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_group_op(input, ALT_BN128_ADD) -} - /// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. /// /// # Arguments @@ -92,30 +69,6 @@ pub fn alt_bn128_multiplication( alt_bn128_group_op(input, ALT_BN128_MUL) } -/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - A G1 point in big-endian (EIP-197) encoding, -/// followed by a scalar in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the multiplication in big-endian (EIP-197) -/// encoding, or an error if the input is invalid. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -#[inline(always)] -pub fn checked_alt_bn128_multiplication( - input: &[u8], -) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_LEN], ProgramError> { - if input.len() > ALT_BN128_MULTIPLICATION_INPUT_LEN { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_group_op(input, ALT_BN128_MUL) -} - /// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. /// /// # Arguments @@ -136,26 +89,6 @@ pub fn alt_bn128_pairing(input: &[u8]) -> Result { alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING).map(|data| data[31]) } -/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. -/// -/// Note: This function checks if the input has the correct length, -/// returning an error without incurring the cost of the syscall. -#[inline(always)] -pub fn checked_alt_bn128_pairing(input: &[u8]) -> Result { - if input.len() % ALT_BN128_PAIRING_ELEMENT_LEN != 0 { - return Err(ProgramError::InvalidArgument); - } - alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING).map(|data| data[31]) -} - #[inline] fn alt_bn128_group_op( input: &[u8], From c536f9b674f1fe1407db75631742d03594ef9651 Mon Sep 17 00:00:00 2001 From: LStan Date: Thu, 18 Sep 2025 03:26:21 +0700 Subject: [PATCH 06/11] add _be suffix --- sdk/pinocchio/src/curves/bn254/compression.rs | 24 +++++++++---------- sdk/pinocchio/src/curves/bn254/group_op.rs | 20 ++++++++-------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/compression.rs b/sdk/pinocchio/src/curves/bn254/compression.rs index 2550e837..e92edbe1 100644 --- a/sdk/pinocchio/src/curves/bn254/compression.rs +++ b/sdk/pinocchio/src/curves/bn254/compression.rs @@ -11,10 +11,10 @@ pub const ALT_BN128_G1_COMPRESSED_POINT_SIZE: usize = ALT_BN128_G1_POINT_SIZE / pub const ALT_BN128_G2_COMPRESSED_POINT_SIZE: usize = ALT_BN128_G2_POINT_SIZE / 2; // 64 // compression operations -const ALT_BN128_G1_COMPRESS: u64 = 0; -const ALT_BN128_G1_DECOMPRESS: u64 = 1; -const ALT_BN128_G2_COMPRESS: u64 = 2; -const ALT_BN128_G2_DECOMPRESS: u64 = 3; +const ALT_BN128_G1_COMPRESS_BE: u64 = 0; +const ALT_BN128_G1_DECOMPRESS_BE: u64 = 1; +const ALT_BN128_G2_COMPRESS_BE: u64 = 2; +const ALT_BN128_G2_DECOMPRESS_BE: u64 = 3; /// Compress a G1 point on the BN254 curve. /// @@ -27,10 +27,10 @@ const ALT_BN128_G2_DECOMPRESS: u64 = 3; /// A `Result` containing the compressed G1 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid G1 point. #[inline(always)] -pub fn alt_bn128_g1_compress( +pub fn alt_bn128_g1_compress_be( input: &[u8; ALT_BN128_G1_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ProgramError> { - alt_bn128_compression(input, ALT_BN128_G1_COMPRESS) + alt_bn128_compression(input, ALT_BN128_G1_COMPRESS_BE) } /// Decompress a G1 point on the BN254 curve. @@ -44,10 +44,10 @@ pub fn alt_bn128_g1_compress( /// A `Result` containing the decompressed G1 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid compressed G1 point. #[inline(always)] -pub fn alt_bn128_g1_decompress( +pub fn alt_bn128_g1_decompress_be( input: &[u8; ALT_BN128_G1_COMPRESSED_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G1_POINT_SIZE], ProgramError> { - alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS) + alt_bn128_compression(input, ALT_BN128_G1_DECOMPRESS_BE) } /// Compress a G2 point on the BN254 curve. @@ -61,10 +61,10 @@ pub fn alt_bn128_g1_decompress( /// A `Result` containing the compressed G2 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid G2 point. #[inline(always)] -pub fn alt_bn128_g2_compress( +pub fn alt_bn128_g2_compress_be( input: &[u8; ALT_BN128_G2_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ProgramError> { - alt_bn128_compression(input, ALT_BN128_G2_COMPRESS) + alt_bn128_compression(input, ALT_BN128_G2_COMPRESS_BE) } /// Decompress a G2 point on the BN254 curve. @@ -78,10 +78,10 @@ pub fn alt_bn128_g2_compress( /// A `Result` containing the decompressed G2 point in big-endian (EIP-197) encoding, /// or an error if the input is not a valid compressed G2 point. #[inline(always)] -pub fn alt_bn128_g2_decompress( +pub fn alt_bn128_g2_decompress_be( input: &[u8; ALT_BN128_G2_COMPRESSED_POINT_SIZE], ) -> Result<[u8; ALT_BN128_G2_POINT_SIZE], ProgramError> { - alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS) + alt_bn128_compression(input, ALT_BN128_G2_DECOMPRESS_BE) } #[inline] diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs index cc639c5c..d28615c4 100644 --- a/sdk/pinocchio/src/curves/bn254/group_op.rs +++ b/sdk/pinocchio/src/curves/bn254/group_op.rs @@ -22,11 +22,11 @@ pub const ALT_BN128_ADDITION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 /// Output length for the multiplication operation. pub const ALT_BN128_MULTIPLICATION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 -const ALT_BN128_ADD: u64 = 0; +const ALT_BN128_G1_ADD_BE: u64 = 0; #[allow(dead_code)] -const ALT_BN128_SUB: u64 = 1; // not implemented in the syscall -const ALT_BN128_MUL: u64 = 2; -const ALT_BN128_PAIRING: u64 = 3; +const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall +const ALT_BN128_G1_MUL_BE: u64 = 2; +const ALT_BN128_PAIRING_BE: u64 = 3; /// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. /// @@ -42,10 +42,10 @@ const ALT_BN128_PAIRING: u64 = 3; /// Note: This function does **not** check if the input has the correct length. /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_addition( +pub fn alt_bn128_g1_addition_be( input: &[u8], ) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_LEN], ProgramError> { - alt_bn128_group_op(input, ALT_BN128_ADD) + alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE) } /// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. @@ -63,10 +63,10 @@ pub fn alt_bn128_addition( /// Note: This function does **not** check if the input has the correct length. /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_multiplication( +pub fn alt_bn128_g1_multiplication_be( input: &[u8], ) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_LEN], ProgramError> { - alt_bn128_group_op(input, ALT_BN128_MUL) + alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE) } /// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. @@ -85,8 +85,8 @@ pub fn alt_bn128_multiplication( /// After SIMD-0334 is implemented, it will return an error if the length is invalid, /// incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_pairing(input: &[u8]) -> Result { - alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING).map(|data| data[31]) +pub fn alt_bn128_pairing_be(input: &[u8]) -> Result { + alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31]) } #[inline] From 6cef48771aeba0d83c64258918ab8852fb865e6e Mon Sep 17 00:00:00 2001 From: LStan Date: Fri, 19 Sep 2025 23:00:58 +0700 Subject: [PATCH 07/11] change suffix from LEN to SIZE --- sdk/pinocchio/src/curves/bn254/compression.rs | 6 ++-- sdk/pinocchio/src/curves/bn254/group_op.rs | 32 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/compression.rs b/sdk/pinocchio/src/curves/bn254/compression.rs index e92edbe1..28e832d8 100644 --- a/sdk/pinocchio/src/curves/bn254/compression.rs +++ b/sdk/pinocchio/src/curves/bn254/compression.rs @@ -85,14 +85,14 @@ pub fn alt_bn128_g2_decompress_be( } #[inline] -fn alt_bn128_compression( +fn alt_bn128_compression( input: &[u8], op: u64, -) -> Result<[u8; OUTPUT_DATA_LEN], ProgramError> { +) -> Result<[u8; OUTPUT_DATA_SIZE], ProgramError> { // Call via a system call to perform the calculation #[cfg(target_os = "solana")] { - let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_LEN]>::uninit(); + let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_SIZE]>::uninit(); let result = unsafe { sol_alt_bn128_compression( diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs index d28615c4..c5295be0 100644 --- a/sdk/pinocchio/src/curves/bn254/group_op.rs +++ b/sdk/pinocchio/src/curves/bn254/group_op.rs @@ -6,21 +6,21 @@ use crate::program_error::ProgramError; #[cfg(target_os = "solana")] use crate::syscalls::sol_alt_bn128_group_op; -/// Input length for the add operation. -pub const ALT_BN128_ADDITION_INPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128 +/// Input size for the add operation. +pub const ALT_BN128_ADDITION_INPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128 -/// Input length for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_INPUT_LEN: usize = +/// Input size for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_INPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_FIELD_SIZE; // 96 -/// Pair element length. -pub const ALT_BN128_PAIRING_ELEMENT_LEN: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192 +/// Pair element size. +pub const ALT_BN128_PAIRING_ELEMENT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192 -/// Output length for the add operation. -pub const ALT_BN128_ADDITION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 +/// Output size for the add operation. +pub const ALT_BN128_ADDITION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 -/// Output length for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_OUTPUT_LEN: usize = ALT_BN128_G1_POINT_SIZE; // 64 +/// Output size for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 const ALT_BN128_G1_ADD_BE: u64 = 0; #[allow(dead_code)] @@ -44,7 +44,7 @@ const ALT_BN128_PAIRING_BE: u64 = 3; #[inline(always)] pub fn alt_bn128_g1_addition_be( input: &[u8], -) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_LEN], ProgramError> { +) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_SIZE], ProgramError> { alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE) } @@ -65,7 +65,7 @@ pub fn alt_bn128_g1_addition_be( #[inline(always)] pub fn alt_bn128_g1_multiplication_be( input: &[u8], -) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_LEN], ProgramError> { +) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_SIZE], ProgramError> { alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE) } @@ -81,7 +81,7 @@ pub fn alt_bn128_g1_multiplication_be( /// /// Note: This function does **not** check if the input has the correct length. /// Currently, if the length is invalid, it will not return an error; instead it will use only -/// multiples of [`ALT_BN128_PAIRING_ELEMENT_LEN`] bytes and discard the rest. +/// multiples of [`ALT_BN128_PAIRING_ELEMENT_SIZE`] bytes and discard the rest. /// After SIMD-0334 is implemented, it will return an error if the length is invalid, /// incurring the cost of the syscall. #[inline(always)] @@ -90,14 +90,14 @@ pub fn alt_bn128_pairing_be(input: &[u8]) -> Result { } #[inline] -fn alt_bn128_group_op( +fn alt_bn128_group_op( input: &[u8], op: u64, -) -> Result<[u8; OUTPUT_DATA_LEN], ProgramError> { +) -> Result<[u8; OUTPUT_DATA_SIZE], ProgramError> { // Call via a system call to perform the calculation #[cfg(target_os = "solana")] { - let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_LEN]>::uninit(); + let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_SIZE]>::uninit(); let result = unsafe { sol_alt_bn128_group_op( From 1521eb81a4ddc8f020f8d8573fdd22ee8dceb2b4 Mon Sep 17 00:00:00 2001 From: LStan Date: Sat, 20 Sep 2025 16:51:24 +0700 Subject: [PATCH 08/11] split group_ops --- sdk/pinocchio/src/curves/bn254/addition.rs | 34 +++++ sdk/pinocchio/src/curves/bn254/group_op.rs | 123 ------------------ sdk/pinocchio/src/curves/bn254/mod.rs | 46 ++++++- .../src/curves/bn254/multiplication.rs | 34 +++++ sdk/pinocchio/src/curves/bn254/pairing.rs | 29 +++++ 5 files changed, 141 insertions(+), 125 deletions(-) create mode 100644 sdk/pinocchio/src/curves/bn254/addition.rs delete mode 100644 sdk/pinocchio/src/curves/bn254/group_op.rs create mode 100644 sdk/pinocchio/src/curves/bn254/multiplication.rs create mode 100644 sdk/pinocchio/src/curves/bn254/pairing.rs diff --git a/sdk/pinocchio/src/curves/bn254/addition.rs b/sdk/pinocchio/src/curves/bn254/addition.rs new file mode 100644 index 00000000..8d02da10 --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/addition.rs @@ -0,0 +1,34 @@ +//! Addition operations on the BN254 curve. + +use super::{alt_bn128_group_op, ALT_BN128_G1_POINT_SIZE}; +use crate::program_error::ProgramError; + +/// Input size for the add operation. +pub const ALT_BN128_ADDITION_INPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128 + +/// Output size for the add operation. +pub const ALT_BN128_ADDITION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 + +const ALT_BN128_G1_ADD_BE: u64 = 0; +#[allow(dead_code)] +const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall + +/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, +/// or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g1_addition_be( + input: &[u8], +) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_SIZE], ProgramError> { + alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE) +} diff --git a/sdk/pinocchio/src/curves/bn254/group_op.rs b/sdk/pinocchio/src/curves/bn254/group_op.rs deleted file mode 100644 index c5295be0..00000000 --- a/sdk/pinocchio/src/curves/bn254/group_op.rs +++ /dev/null @@ -1,123 +0,0 @@ -//! Group operations on the BN254 curve. - -use super::{ALT_BN128_FIELD_SIZE, ALT_BN128_G1_POINT_SIZE, ALT_BN128_G2_POINT_SIZE}; -use crate::program_error::ProgramError; - -#[cfg(target_os = "solana")] -use crate::syscalls::sol_alt_bn128_group_op; - -/// Input size for the add operation. -pub const ALT_BN128_ADDITION_INPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128 - -/// Input size for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_INPUT_SIZE: usize = - ALT_BN128_G1_POINT_SIZE + ALT_BN128_FIELD_SIZE; // 96 - -/// Pair element size. -pub const ALT_BN128_PAIRING_ELEMENT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192 - -/// Output size for the add operation. -pub const ALT_BN128_ADDITION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 - -/// Output size for the multiplication operation. -pub const ALT_BN128_MULTIPLICATION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 - -const ALT_BN128_G1_ADD_BE: u64 = 0; -#[allow(dead_code)] -const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall -const ALT_BN128_G1_MUL_BE: u64 = 2; -const ALT_BN128_PAIRING_BE: u64 = 3; - -/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, -/// or an error if the input is invalid. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. -#[inline(always)] -pub fn alt_bn128_g1_addition_be( - input: &[u8], -) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_SIZE], ProgramError> { - alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE) -} - -/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - A G1 point in big-endian (EIP-197) encoding, -/// followed by a scalar in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the multiplication in big-endian (EIP-197) -/// encoding, or an error if the input is invalid. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. -#[inline(always)] -pub fn alt_bn128_g1_multiplication_be( - input: &[u8], -) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_SIZE], ProgramError> { - alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE) -} - -/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. -/// -/// # Arguments -/// -/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding. -/// -/// # Returns -/// -/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. -/// -/// Note: This function does **not** check if the input has the correct length. -/// Currently, if the length is invalid, it will not return an error; instead it will use only -/// multiples of [`ALT_BN128_PAIRING_ELEMENT_SIZE`] bytes and discard the rest. -/// After SIMD-0334 is implemented, it will return an error if the length is invalid, -/// incurring the cost of the syscall. -#[inline(always)] -pub fn alt_bn128_pairing_be(input: &[u8]) -> Result { - alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31]) -} - -#[inline] -fn alt_bn128_group_op( - input: &[u8], - op: u64, -) -> Result<[u8; OUTPUT_DATA_SIZE], ProgramError> { - // Call via a system call to perform the calculation - #[cfg(target_os = "solana")] - { - let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_SIZE]>::uninit(); - - let result = unsafe { - sol_alt_bn128_group_op( - op, - input as *const _ as *const u8, - input.len() as u64, - bytes.as_mut_ptr() as *mut u8, - ) - }; - - match result { - // SAFETY: The syscall has initialized the bytes. - crate::SUCCESS => Ok(unsafe { bytes.assume_init() }), - _ => Err(ProgramError::InvalidArgument), - } - } - - #[cfg(not(target_os = "solana"))] - { - core::hint::black_box((input, op)); - panic!("alt_bn128_group_op is only available on target `solana`") - } -} diff --git a/sdk/pinocchio/src/curves/bn254/mod.rs b/sdk/pinocchio/src/curves/bn254/mod.rs index 481a4df0..68d9bd78 100644 --- a/sdk/pinocchio/src/curves/bn254/mod.rs +++ b/sdk/pinocchio/src/curves/bn254/mod.rs @@ -1,10 +1,19 @@ //! BN254 curve operations +pub mod addition; pub mod compression; -pub mod group_op; +pub mod multiplication; +pub mod pairing; +pub use addition::*; pub use compression::*; -pub use group_op::*; +pub use multiplication::*; +pub use pairing::*; + +use crate::program_error::ProgramError; + +#[cfg(target_os = "solana")] +use crate::syscalls::sol_alt_bn128_group_op; /// Size of the EC point field, in bytes. pub const ALT_BN128_FIELD_SIZE: usize = 32; @@ -12,3 +21,36 @@ pub const ALT_BN128_FIELD_SIZE: usize = 32; pub const ALT_BN128_G1_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 2; /// Elements in G2 is represented by 2 field-extension elements `(x, y)`. pub const ALT_BN128_G2_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 4; + +#[inline] +fn alt_bn128_group_op( + input: &[u8], + op: u64, +) -> Result<[u8; OUTPUT_DATA_SIZE], ProgramError> { + // Call via a system call to perform the calculation + #[cfg(target_os = "solana")] + { + let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_SIZE]>::uninit(); + + let result = unsafe { + sol_alt_bn128_group_op( + op, + input as *const _ as *const u8, + input.len() as u64, + bytes.as_mut_ptr() as *mut u8, + ) + }; + + match result { + // SAFETY: The syscall has initialized the bytes. + crate::SUCCESS => Ok(unsafe { bytes.assume_init() }), + _ => Err(ProgramError::InvalidArgument), + } + } + + #[cfg(not(target_os = "solana"))] + { + core::hint::black_box((input, op)); + panic!("alt_bn128_group_op is only available on target `solana`") + } +} diff --git a/sdk/pinocchio/src/curves/bn254/multiplication.rs b/sdk/pinocchio/src/curves/bn254/multiplication.rs new file mode 100644 index 00000000..dbf8d1a4 --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/multiplication.rs @@ -0,0 +1,34 @@ +//! Multiplication operations on the BN254 curve. + +use super::{alt_bn128_group_op, ALT_BN128_FIELD_SIZE, ALT_BN128_G1_POINT_SIZE}; +use crate::program_error::ProgramError; + +/// Input size for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_INPUT_SIZE: usize = + ALT_BN128_G1_POINT_SIZE + ALT_BN128_FIELD_SIZE; // 96 + +/// Output size for the multiplication operation. +pub const ALT_BN128_MULTIPLICATION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64 + +const ALT_BN128_G1_MUL_BE: u64 = 2; + +/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A G1 point in big-endian (EIP-197) encoding, +/// followed by a scalar in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the multiplication in big-endian (EIP-197) +/// encoding, or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// It will return an error if the length is invalid, incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_g1_multiplication_be( + input: &[u8], +) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_SIZE], ProgramError> { + alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE) +} diff --git a/sdk/pinocchio/src/curves/bn254/pairing.rs b/sdk/pinocchio/src/curves/bn254/pairing.rs new file mode 100644 index 00000000..993e715f --- /dev/null +++ b/sdk/pinocchio/src/curves/bn254/pairing.rs @@ -0,0 +1,29 @@ +//! Pairing operations on the BN254 curve. + +use super::{alt_bn128_group_op, ALT_BN128_G1_POINT_SIZE, ALT_BN128_G2_POINT_SIZE}; +use crate::program_error::ProgramError; + +/// Pair element size. +pub const ALT_BN128_PAIRING_ELEMENT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192 + +const ALT_BN128_PAIRING_BE: u64 = 3; + +/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. +/// +/// # Arguments +/// +/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding. +/// +/// # Returns +/// +/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. +/// +/// Note: This function does **not** check if the input has the correct length. +/// Currently, if the length is invalid, it will not return an error; instead it will use only +/// multiples of [`ALT_BN128_PAIRING_ELEMENT_SIZE`] bytes and discard the rest. +/// After SIMD-0334 is implemented, it will return an error if the length is invalid, +/// incurring the cost of the syscall. +#[inline(always)] +pub fn alt_bn128_pairing_be(input: &[u8]) -> Result { + alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31]) +} From f11441ad92fd019f05c59283113ac68ca5379bb2 Mon Sep 17 00:00:00 2001 From: LStan Date: Sun, 21 Sep 2025 20:53:03 +0700 Subject: [PATCH 09/11] change input type for addition and multiplication --- sdk/pinocchio/src/curves/bn254/addition.rs | 2 +- sdk/pinocchio/src/curves/bn254/multiplication.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/addition.rs b/sdk/pinocchio/src/curves/bn254/addition.rs index 8d02da10..7c6ccf01 100644 --- a/sdk/pinocchio/src/curves/bn254/addition.rs +++ b/sdk/pinocchio/src/curves/bn254/addition.rs @@ -28,7 +28,7 @@ const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_addition_be( - input: &[u8], + input: &[u8; ALT_BN128_ADDITION_INPUT_SIZE], ) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_SIZE], ProgramError> { alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE) } diff --git a/sdk/pinocchio/src/curves/bn254/multiplication.rs b/sdk/pinocchio/src/curves/bn254/multiplication.rs index dbf8d1a4..6271c90d 100644 --- a/sdk/pinocchio/src/curves/bn254/multiplication.rs +++ b/sdk/pinocchio/src/curves/bn254/multiplication.rs @@ -28,7 +28,7 @@ const ALT_BN128_G1_MUL_BE: u64 = 2; /// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_multiplication_be( - input: &[u8], + input: &[u8; ALT_BN128_MULTIPLICATION_INPUT_SIZE], ) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_SIZE], ProgramError> { alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE) } From b6b9ea6ac369d89d950a323b1c536aee4efb6e9a Mon Sep 17 00:00:00 2001 From: LStan Date: Wed, 24 Sep 2025 20:07:49 +0700 Subject: [PATCH 10/11] fix comments --- sdk/pinocchio/src/curves/bn254/addition.rs | 3 --- sdk/pinocchio/src/curves/bn254/multiplication.rs | 3 --- 2 files changed, 6 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/addition.rs b/sdk/pinocchio/src/curves/bn254/addition.rs index 7c6ccf01..140e2bbe 100644 --- a/sdk/pinocchio/src/curves/bn254/addition.rs +++ b/sdk/pinocchio/src/curves/bn254/addition.rs @@ -23,9 +23,6 @@ const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall /// /// A `Result` containing the result of the addition in big-endian (EIP-197) encoding, /// or an error if the input is invalid. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_addition_be( input: &[u8; ALT_BN128_ADDITION_INPUT_SIZE], diff --git a/sdk/pinocchio/src/curves/bn254/multiplication.rs b/sdk/pinocchio/src/curves/bn254/multiplication.rs index 6271c90d..92274a84 100644 --- a/sdk/pinocchio/src/curves/bn254/multiplication.rs +++ b/sdk/pinocchio/src/curves/bn254/multiplication.rs @@ -23,9 +23,6 @@ const ALT_BN128_G1_MUL_BE: u64 = 2; /// /// A `Result` containing the result of the multiplication in big-endian (EIP-197) /// encoding, or an error if the input is invalid. -/// -/// Note: This function does **not** check if the input has the correct length. -/// It will return an error if the length is invalid, incurring the cost of the syscall. #[inline(always)] pub fn alt_bn128_g1_multiplication_be( input: &[u8; ALT_BN128_MULTIPLICATION_INPUT_SIZE], From 5f8281f9060e662a969f7b6b3a2629431adc9c88 Mon Sep 17 00:00:00 2001 From: LStan Date: Sun, 26 Oct 2025 00:07:22 +0700 Subject: [PATCH 11/11] change pairing return type to bool --- sdk/pinocchio/src/curves/bn254/pairing.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sdk/pinocchio/src/curves/bn254/pairing.rs b/sdk/pinocchio/src/curves/bn254/pairing.rs index 993e715f..088c6e2d 100644 --- a/sdk/pinocchio/src/curves/bn254/pairing.rs +++ b/sdk/pinocchio/src/curves/bn254/pairing.rs @@ -8,7 +8,8 @@ pub const ALT_BN128_PAIRING_ELEMENT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_ const ALT_BN128_PAIRING_BE: u64 = 3; -/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding. +/// Checks whether the product of pairings of a sequence of G1 and G2 points (in big-endian EIP-197 encoding) +/// on the BN254 curve evaluates to the identity element (1). /// /// # Arguments /// @@ -16,7 +17,10 @@ const ALT_BN128_PAIRING_BE: u64 = 3; /// /// # Returns /// -/// A `Result` containing the result of the pairing operation, or an error if the input is invalid. +/// A `Result` containing: +/// - `Ok(true)` if the pairing product equals 1, +/// - `Ok(false)` otherwise, +/// - `Err(ProgramError)` if the input is invalid. /// /// Note: This function does **not** check if the input has the correct length. /// Currently, if the length is invalid, it will not return an error; instead it will use only @@ -24,6 +28,6 @@ const ALT_BN128_PAIRING_BE: u64 = 3; /// After SIMD-0334 is implemented, it will return an error if the length is invalid, /// incurring the cost of the syscall. #[inline(always)] -pub fn alt_bn128_pairing_be(input: &[u8]) -> Result { - alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31]) +pub fn alt_bn128_is_pairing_valid_be(input: &[u8]) -> Result { + alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31] == 1) }