Skip to main content
Technical proposal SIMD-0284 Idea

Alt-BN128 Little Endian compatibility

  1. Idea
  2. Draft
  3. Review
  4. Accept
  5. Implement
  6. Active

Decision brief

Why this proposal matters

Extend the Alt-BN128 syscalls to add little endian support.

Source-backed reading aid · source language: EN

Proposal at a glance

What changes

  • Extend the Alt-BN128 syscalls to add little endian support.

Stakeholder map

Who is affected

Builders & client teams Medium impact

These options could then be added to the relevant SDKs (solana-bn254), potentially with an optional feature flag to enable/disable big and little endian variants.

Action requirement unknown
Validators & operators Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Users & stakers Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown
Governance & ecosystem Impact unknown

No proposal-specific evidence was found for this group.

Action requirement unknown

Exact source revision

Full proposal document

Source-language document. Technical identifiers and evidence remain unchanged. 0616093b2952

Summary

Extend the Alt-BN128 syscalls to add little endian support.

Motivation

All prominent ZK teams on Solana primarily use Rust with ark-bn254 in their workflows; the same crate used in the Alt-BN128 syscalls implementation in agave. The original implementor designed the syscalls to mimic the functionality of Ethereum which encodes uint256 values in Big Endian.

This creates an unnecessarily complicated API for anyone trying to build zero knowledge proofs on Solana leading to many wasted hours of debugging endianness and encoding issues. As it's relatively easy to fix, we should do something about it.

New Terminology

N/A

Detailed Design

There are two Alt-BN128 syscalls:

sol_alt_bn128_group_op and sol_alt_bn128_compression.

Each takes in an argument to determine which operation they are performing as their first parameter.

In the case of sol_alt_bn128_group_op:

pub const ALT_BN128_ADD: u64 = 0;
pub const ALT_BN128_SUB: u64 = 1;
pub const ALT_BN128_MUL: u64 = 2;
pub const ALT_BN128_PAIRING: u64 = 3;

In the case of sol_alt_bn128_compression:

pub const ALT_BN128_G1_COMPRESS: u64 = 0;
pub const ALT_BN128_G1_DECOMPRESS: u64 = 1;
pub const ALT_BN128_G2_COMPRESS: u64 = 2;
pub const ALT_BN128_G2_DECOMPRESS: u64 = 3;

This SIMD proposes we include four new values for each of these syscalls with a bitmask of 0x80 to signal their little endian equivalents:

pub const ALT_BN128_ADD_LE: u64 = ALT_BN128_ADD | 0x80;
pub const ALT_BN128_SUB_LE: u64 = ALT_BN128_SUB | 0x80;
pub const ALT_BN128_MUL_LE: u64 = ALT_BN128_MUL | 0x80;
pub const ALT_BN128_PAIRING_LE: u64 = ALT_BN128_PAIRING | 0x80;

In the case of sol_alt_bn128_compression

pub const ALT_BN128_G1_COMPRESS_LE: u64 = ALT_BN128_G1_COMPRESS | 0x80;
pub const ALT_BN128_G1_DECOMPRESS_LE: u64 = ALT_BN128_G1_DECOMPRESS | 0x80;
pub const ALT_BN128_G2_COMPRESS_LE: u64 = ALT_BN128_G2_COMPRESS | 0x80;
pub const ALT_BN128_G2_DECOMPRESS_LE: u64 = ALT_BN128_G2_DECOMPRESS | 0x80;

These options could then be added to the relevant SDKs (solana-bn254), potentially with an optional feature flag to enable/disable big and little endian variants.

Alternatives Considered

Overhaul Rust-based ZK tooling itself to become more Ethereum-compatible.

Impact

Working with ZK proofs will become much easier, as the most widely-used tooling and the system API will finally be compatible without any additional work or confusion.

Security Considerations

None

Evidence graph

Related proposals and rollout

One or more sources are unavailable.

Upstream review record

Upstream discussion & review

GitHub review is editorial context, not evidence of on-chain support, voting, or outcome.

PR #284 · merged SIMD-0284: Alt-BN128 Little Endian Compatibility 11 comments and reviews · Jan 19, 2026
@samkim-crypto

I guess the reason why we went with the BE route for bn128 syscalls was to conform to the Ethereum precompiles. So including the Eth compatibility issues here might not make that much sense. Maybe we can do things more iteratively as @jacobcreech mentioned. But I actually can't think of a definite argument against why we can have an intermediate sdk that wraps the curve syscalls and does the translations for consumers. If the sdk is well-documented and we encourage all the big projects to use them instead of the syscalls directly, then this may quickly become a standard? In this case, we may not need all these iterations of simds to modify the runtime.

GitHub ↗
@0x0ece

@samkim-crypto I also like the sdk idea. and good to do iterations as @jacobcreech recommends. @deanmlittle for context, this was an inspiration: https://docs.succinct.xyz/docs/sp1/optimizing-programs/precompiles in time this solana crypto sdk can become a transparent replacement for common rust crypto libs that uses the right syscalls at the right time.

GitHub ↗
@deanmlittle

Yeah I am okay with this as well. If we move forward with this, then as @0x0ece mentioned, we should take care of all the Eth compatibility issues together. For example, maybe we can include a fix to this issue(https://github.com/anza-xyz/agave/issues/3379) in the simd as well. An alternative would be to leave the syscall the same and then create something like a solana-curve-sdk that contain syscall wrapper functions (wrappers to solaltbn128groupop, solaltbn128compression) that does the encoding (endianness) translation before invoking the relevant syscalls. The translations should be executable as BPF instructions. If we have a single curve sdk that can be consumed commonly by downstream p

GitHub ↗
@samkim-crypto

Right, the flags are only used during serialization/deserialization. We just ignore the flags in Solana while on Ethereum, the precompile functions error out when the flags are set. So if we follow the Ethereum convention, then we are indeed making the syscall functions more restrictive. I think the main philosophical decision we have to make is whether we should follow the Ethereum convention or have our own conventions for the curve syscalls. The main argument for the former is that it would minimize confusion for projects that are migrating from Ethereum to Solana. The choice of big-endian encoding stemmed from following the Ethereum convention as well. But like you said, I think it makes

GitHub ↗
@vadorovsky

@samkim-crypto An alternative would be to leave the syscall the same and then create something like a solana-curve-sdk that contain syscall wrapper functions (wrappers to solaltbn128groupop, solaltbn128compression) that does the encoding (endianness) translation before invoking the relevant syscalls. My only concern with that approach is that it requires SBPF programs to spend their cycles on inverting bytes. Especially if we leave syscall as BE, then practically the most of consumers would end up doing that conversion... That's the reason why I added an explicit argument to the Poseidon syscall - to appease both native arkworks users and Ethereum bridges while not forcing people to spend CU

GitHub ↗
@jacobcreech

the main philosophical decision we have to make is whether we should follow the Ethereum convention or have our own conventions for the curve syscalls I'm on the side that we learn from Ethereum conventions but build what makes sense for Solana. Sometimes that means the same convention, but in cases like this SIMD it means being different. an explicit enum argument for determining endiannes, which I added to appease both arkworks users and Ethereum-related projects This is actually a pretty elegant solution that supports both camps here.

GitHub ↗
@deanmlittle

My only concern with that approach is that it requires SBPF programs to spend their cycles on inverting bytes. Especially if we leave syscall as BE, then practically the most of consumers would end up doing that conversion... That's the reason why I added an explicit argument to the Poseidon syscall - to appease both native arkworks users and Ethereum bridges while not forcing people to spend CU in either case. +1. I also like the approach you took with Poseidon and think the bitmask approach in this case is the most analogous and least invasive way to go about it. I would like to think that we care more about improving the real devex issues that our own developers are facing today over the

GitHub ↗
@deanmlittle

I see mostly agreement from the relevant stakeholders and no major pushbacks. Can we go ahead and merge this one?

GitHub ↗

simd.watch community discussion · SIMD-0284

Powered by Giscus · Sign in with GitHub to comment

Community comments load when this section approaches the viewport.

Provenance

Evidence & technical details

Rollout or chain data, source revisions, freshness and integrity.
1

SIMD

Deployment Status

Document lifecycleIdea
CategoryCore protocol

Feature Gate not yet created

Exact source revision

Sources & integrity

  • Proposal document pinned_commit_blob
    0616093b2952ed6de52c4a27d66aadd11d48d4f9
  • simd-document document · current · Sep 11, 2026
    0616093b2952ed6de52c4a27d66aadd11d48d4f9

One or more sources are unavailable.