Skip to content

Commit 1521eb8

Browse files
committed
split group_ops
1 parent 6cef487 commit 1521eb8

File tree

5 files changed

+141
-125
lines changed

5 files changed

+141
-125
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//! Addition operations on the BN254 curve.
2+
3+
use super::{alt_bn128_group_op, ALT_BN128_G1_POINT_SIZE};
4+
use crate::program_error::ProgramError;
5+
6+
/// Input size for the add operation.
7+
pub const ALT_BN128_ADDITION_INPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE * 2; // 128
8+
9+
/// Output size for the add operation.
10+
pub const ALT_BN128_ADDITION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64
11+
12+
const ALT_BN128_G1_ADD_BE: u64 = 0;
13+
#[allow(dead_code)]
14+
const ALT_BN128_G1_SUB_BE: u64 = 1; // not implemented in the syscall
15+
16+
/// Add two G1 points on the BN254 curve in big-endian (EIP-197) encoding.
17+
///
18+
/// # Arguments
19+
///
20+
/// * `input` - Two consecutive G1 points in big-endian (EIP-197) encoding.
21+
///
22+
/// # Returns
23+
///
24+
/// A `Result` containing the result of the addition in big-endian (EIP-197) encoding,
25+
/// or an error if the input is invalid.
26+
///
27+
/// Note: This function does **not** check if the input has the correct length.
28+
/// It will return an error if the length is invalid, incurring the cost of the syscall.
29+
#[inline(always)]
30+
pub fn alt_bn128_g1_addition_be(
31+
input: &[u8],
32+
) -> Result<[u8; ALT_BN128_ADDITION_OUTPUT_SIZE], ProgramError> {
33+
alt_bn128_group_op(input, ALT_BN128_G1_ADD_BE)
34+
}

sdk/pinocchio/src/curves/bn254/group_op.rs

Lines changed: 0 additions & 123 deletions
This file was deleted.
Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,56 @@
11
//! BN254 curve operations
22
3+
pub mod addition;
34
pub mod compression;
4-
pub mod group_op;
5+
pub mod multiplication;
6+
pub mod pairing;
57

8+
pub use addition::*;
69
pub use compression::*;
7-
pub use group_op::*;
10+
pub use multiplication::*;
11+
pub use pairing::*;
12+
13+
use crate::program_error::ProgramError;
14+
15+
#[cfg(target_os = "solana")]
16+
use crate::syscalls::sol_alt_bn128_group_op;
817

918
/// Size of the EC point field, in bytes.
1019
pub const ALT_BN128_FIELD_SIZE: usize = 32;
1120
/// A group element in G1 consists of two field elements `(x, y)`.
1221
pub const ALT_BN128_G1_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 2;
1322
/// Elements in G2 is represented by 2 field-extension elements `(x, y)`.
1423
pub const ALT_BN128_G2_POINT_SIZE: usize = ALT_BN128_FIELD_SIZE * 4;
24+
25+
#[inline]
26+
fn alt_bn128_group_op<const OUTPUT_DATA_SIZE: usize>(
27+
input: &[u8],
28+
op: u64,
29+
) -> Result<[u8; OUTPUT_DATA_SIZE], ProgramError> {
30+
// Call via a system call to perform the calculation
31+
#[cfg(target_os = "solana")]
32+
{
33+
let mut bytes = core::mem::MaybeUninit::<[u8; OUTPUT_DATA_SIZE]>::uninit();
34+
35+
let result = unsafe {
36+
sol_alt_bn128_group_op(
37+
op,
38+
input as *const _ as *const u8,
39+
input.len() as u64,
40+
bytes.as_mut_ptr() as *mut u8,
41+
)
42+
};
43+
44+
match result {
45+
// SAFETY: The syscall has initialized the bytes.
46+
crate::SUCCESS => Ok(unsafe { bytes.assume_init() }),
47+
_ => Err(ProgramError::InvalidArgument),
48+
}
49+
}
50+
51+
#[cfg(not(target_os = "solana"))]
52+
{
53+
core::hint::black_box((input, op));
54+
panic!("alt_bn128_group_op is only available on target `solana`")
55+
}
56+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//! Multiplication operations on the BN254 curve.
2+
3+
use super::{alt_bn128_group_op, ALT_BN128_FIELD_SIZE, ALT_BN128_G1_POINT_SIZE};
4+
use crate::program_error::ProgramError;
5+
6+
/// Input size for the multiplication operation.
7+
pub const ALT_BN128_MULTIPLICATION_INPUT_SIZE: usize =
8+
ALT_BN128_G1_POINT_SIZE + ALT_BN128_FIELD_SIZE; // 96
9+
10+
/// Output size for the multiplication operation.
11+
pub const ALT_BN128_MULTIPLICATION_OUTPUT_SIZE: usize = ALT_BN128_G1_POINT_SIZE; // 64
12+
13+
const ALT_BN128_G1_MUL_BE: u64 = 2;
14+
15+
/// Multiply a G1 point by a scalar on the BN254 curve in big-endian (EIP-197) encoding.
16+
///
17+
/// # Arguments
18+
///
19+
/// * `input` - A G1 point in big-endian (EIP-197) encoding,
20+
/// followed by a scalar in big-endian (EIP-197) encoding.
21+
///
22+
/// # Returns
23+
///
24+
/// A `Result` containing the result of the multiplication in big-endian (EIP-197)
25+
/// encoding, or an error if the input is invalid.
26+
///
27+
/// Note: This function does **not** check if the input has the correct length.
28+
/// It will return an error if the length is invalid, incurring the cost of the syscall.
29+
#[inline(always)]
30+
pub fn alt_bn128_g1_multiplication_be(
31+
input: &[u8],
32+
) -> Result<[u8; ALT_BN128_MULTIPLICATION_OUTPUT_SIZE], ProgramError> {
33+
alt_bn128_group_op(input, ALT_BN128_G1_MUL_BE)
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! Pairing operations on the BN254 curve.
2+
3+
use super::{alt_bn128_group_op, ALT_BN128_G1_POINT_SIZE, ALT_BN128_G2_POINT_SIZE};
4+
use crate::program_error::ProgramError;
5+
6+
/// Pair element size.
7+
pub const ALT_BN128_PAIRING_ELEMENT_SIZE: usize = ALT_BN128_G1_POINT_SIZE + ALT_BN128_G2_POINT_SIZE; // 192
8+
9+
const ALT_BN128_PAIRING_BE: u64 = 3;
10+
11+
/// Perform a pairing operation on the BN254 curve in big-endian (EIP-197) encoding.
12+
///
13+
/// # Arguments
14+
///
15+
/// * `input` - A sequence of pairs of G1 and G2 points in big-endian (EIP-197) encoding.
16+
///
17+
/// # Returns
18+
///
19+
/// A `Result` containing the result of the pairing operation, or an error if the input is invalid.
20+
///
21+
/// Note: This function does **not** check if the input has the correct length.
22+
/// Currently, if the length is invalid, it will not return an error; instead it will use only
23+
/// multiples of [`ALT_BN128_PAIRING_ELEMENT_SIZE`] bytes and discard the rest.
24+
/// After SIMD-0334 is implemented, it will return an error if the length is invalid,
25+
/// incurring the cost of the syscall.
26+
#[inline(always)]
27+
pub fn alt_bn128_pairing_be(input: &[u8]) -> Result<u8, ProgramError> {
28+
alt_bn128_group_op::<32>(input, ALT_BN128_PAIRING_BE).map(|data| data[31])
29+
}

0 commit comments

Comments
 (0)