Skip to content

0xct0/solana-bulletproofs-rangeproof

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

1 Commit
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

8-bit Bulletproof Range Proofs on Solana

A proof-of-concept implementation of Bulletproof range proofs on Solana, enabling zero-knowledge verification that a committed value lies within the range [0, 255].

Are you a Solana/ZK company?

Im open to submit a resume :)

๐Ÿ”‘ Key Innovation: Syscall Jailbreak

This implementation leverages the secp256k1 syscall jailbreak technique pioneered by deanmlittle/solana-secp256k1. Instead of implementing expensive elliptic curve scalar multiplication from scratch (which would blow through compute limits), we abuse the secp256k1_recover syscall to perform arbitrary EC operations at syscall-level efficiency.

The trick: secp256k1_recover is designed for signature recovery, but with carefully crafted inputs, we can coerce it into performing scalar multiplication:

// Fake "signature" that actually computes k * P
let s = mul_mod(k, &p.x, &CURVE_N);
let mut sig = [0u8; 64];
sig[0..32].copy_from_slice(&p.x.to_be_bytes());
sig[32..64].copy_from_slice(&s.to_be_bytes());
let recovered = secp256k1_recover(&[0u8; 32], recovery_id, &sig)?;

This gives us ~25,000 CU EC multiplications which makes this all possible (Thank you Dean).


๐Ÿ—๏ธ Architecture

Two Components

bp8/
โ”œโ”€โ”€ program/           # On-chain Solana program (lib.rs)
โ”‚   โ””โ”€โ”€ lib.rs         # Bulletproof verifier (~1600 lines)
โ””โ”€โ”€ client/            # Off-chain Rust client (main.rs)
    โ””โ”€โ”€ main.rs        # Proof generation + transaction submission

On-Chain State

The verifier uses two PDAs:

PDA Seed Purpose
Generator PDA ["bp8-gen"] Stores 18 elliptic curve generator points (1152 bytes)
State PDA ["bp8-state", payer, nonce] Per-proof verification state (8 KB)

๐Ÿ“Š Execution Flow

Phase 1: Setup (One-time)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    GENERATOR SETUP                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  1. OP_CREATE_GEN (0x01)                                    โ”‚
โ”‚     โ””โ”€ Creates generator PDA                                โ”‚
โ”‚                                                             โ”‚
โ”‚  2. OP_WRITE_GENERATORS (0x02) ร— N chunks                   โ”‚
โ”‚     โ””โ”€ Uploads 18 generator points:                         โ”‚
โ”‚        โ€ข H (blinding base)                                  โ”‚
โ”‚        โ€ข G (value base)                                     โ”‚
โ”‚        โ€ข g_0..g_7 (vector bases)                            โ”‚
โ”‚        โ€ข h_0..h_7 (vector bases)                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Phase 2: Proof Generation (Off-chain)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 CLIENT: prove_range()                       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Input: value (u64), gamma (random blinding)                โ”‚
โ”‚                                                             โ”‚
โ”‚  1. Pedersen Commitment                                     โ”‚
โ”‚     V = valueยทG + gammaยทH                                   โ”‚
โ”‚                                                             โ”‚
โ”‚  2. Bit Decomposition                                       โ”‚
โ”‚     a_L[i] = (value >> i) & 1                               โ”‚
โ”‚     a_R[i] = a_L[i] - 1                                     โ”‚
โ”‚                                                             โ”‚
โ”‚  3. Vector Commitments (A, S)                               โ”‚
โ”‚     A = alphaยทH + ฮฃ(a_L[i]ยทg_i + a_R[i]ยทh_i)               โ”‚
โ”‚     S = rhoยทH + ฮฃ(s_L[i]ยทg_i + s_R[i]ยทh_i)                 โ”‚
โ”‚                                                             โ”‚
โ”‚  4. Fiat-Shamir Challenges                                  โ”‚
โ”‚     y = H(A, S)                                             โ”‚
โ”‚     z = H(y, V)                                             โ”‚
โ”‚     x = H(z, T1, T2)                                        โ”‚
โ”‚                                                             โ”‚
โ”‚  5. Polynomial Evaluation                                   โ”‚
โ”‚     t_hat = t(x) = t_0 + t_1ยทx + t_2ยทxยฒ                    โ”‚
โ”‚                                                             โ”‚
โ”‚  6. Inner Product Argument (logโ‚‚(n) rounds)                 โ”‚
โ”‚     Produces: L[0..2], R[0..2], a_scalar, b_scalar          โ”‚
โ”‚                                                             โ”‚
โ”‚  Output: 523-byte proof                                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Phase 3: On-chain Verification (56 transactions)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              ON-CHAIN VERIFICATION STEPS                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  OP_CREATE_STATE (0x10)                                     โ”‚
โ”‚  โ””โ”€ Allocate 8KB state PDA                                  โ”‚
โ”‚                                                             โ”‚
โ”‚  OP_INIT_PROOF (0x11)                                       โ”‚
โ”‚  โ””โ”€ Parse proof, compute Fiat-Shamir challenges             โ”‚
โ”‚                                                             โ”‚
โ”‚  OP_VERIFY_STEP (0x20) ร— 56 calls:                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚ Steps 0-10:   Decompress proof points (V,A,S,T1,T2,  โ”‚   โ”‚
โ”‚  โ”‚               L[0-2], R[0-2])                         โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 11-13:  Compute inverse challenges x_j^{-1}     โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 14-16:  Build coefficient tables (y^i, 2^i)     โ”‚   โ”‚
โ”‚  โ”‚               Compute delta                           โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 17-22:  t(x) check LHS/RHS computation          โ”‚   โ”‚
โ”‚  โ”‚               LHS = t_hatยทG + tauxยทH                  โ”‚   โ”‚
โ”‚  โ”‚               RHS = zยฒยทV + deltaยทG + xยทT1 + xยฒยทT2     โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Step 23:      VERIFY: LHS == RHS                      โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 24-35:  Inner product LHS accumulation          โ”‚   โ”‚
โ”‚  โ”‚               A + xยทS + ฮฃxยฒยทL + ฮฃxโปยฒยทR - muยทH        โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 36-37:  Compute IPA weights w_i, w_inv_i        โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Steps 38-54:  Inner product RHS accumulation          โ”‚   โ”‚
โ”‚  โ”‚               (aยทb)ยทU + ฮฃ(aยทw_i)ยทg_i +               โ”‚   โ”‚
โ”‚  โ”‚               ฮฃ(bยทw_inv_iยทy^{-i})ยทh_i                 โ”‚   โ”‚
โ”‚  โ”‚                                                       โ”‚   โ”‚
โ”‚  โ”‚ Step 55:      VERIFY: IP_LHS == IP_RHS                โ”‚   โ”‚
โ”‚  โ”‚               โœ“ PROOF VERIFIED                        โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿš€ Usage

Prerequisites

# Install Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/v1.18.0/install)"

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Deploy the Program

cd onchain
cargo build-sbf
solana program deploy target/deploy/bulletproof.so

Configure the Client

Edit offchain/src/main.rs:

const RPC_URL: &str = "https://api.devnet.solana.com";
const PROGRAM_ID: &str = "<YOUR-PROGRAM-ID>";
const PAYER_B58: &str = "<YOUR-KEYPAIR-BASE58>";

Initialize Generators (One-time)

cd offchain
cargo run -- init-generators

Generate and Verify a Proof

# Prove that 42 is in [0, 255]
cargo run -- prove 42 0

# Prove with a different nonce (for multiple proofs)
cargo run -- prove 100 1

# This will fail (value out of range)
cargo run -- prove 300 2

๐Ÿ“ Proof Structure

The 523-byte proof contains:

Field Size Description
V 33 Pedersen commitment to value
A 33 Vector commitment
S 33 Blinding vector commitment
T1 33 First polynomial commitment
T2 33 Second polynomial commitment
taux 32 Blinding factor
mu 32 Combined blinding
t_hat 32 Polynomial evaluation
a_scalar 32 Final IPA scalar
b_scalar 32 Final IPA scalar
L[0..2] 99 Left IPA commitments (3 ร— 33)
R[0..2] 99 Right IPA commitments (3 ร— 33)

๐ŸŽฏ Use Cases

Private Balance Verification

Prove your token balance is above a threshold without revealing the exact amount.

Blind Auctions

Commit to a bid, prove it's within valid range, reveal only if you win.

Gaming

Hidden stats, health points, or scores that can be verified without exposure.

Age/Credit Verification

Prove you meet a minimum requirement without revealing your exact age or credit score.


โš ๏ธ Current Limitations (POC)

This is a proof of concept. Current limitations:

  1. 56 transactions required - Each verification step is a separate tx
  2. 8-bit range only - Values must be in [0, 255]
  3. No batching - Steps could be combined to reduce tx count
  4. Debug logging - Production would remove verbose logging
  5. Single proof per state PDA - No aggregation yet

๐Ÿ”ฎ Roadmap

Future commits will focus on:

  • Step Consolidation - Batch multiple steps per transaction (many steps use <50k CU)
  • 16/32-bit Support - Extend range to larger values
  • Proof Aggregation - Verify multiple proofs in parallel
  • Gas Optimization - Remove debug logging (onchain and offchain lol)

๐Ÿค Contributing

Are you a Solana/ZK company?

(Im open to submit a resume)

This project is at the intersection of:

  • Zero-knowledge cryptography
  • Solana program optimization
  • Novel syscall exploitation techniques

If you're interested in:

  • Extending to larger bit ranges
  • Implementing other ZK primitives (Groth16)
  • Building applications on top of this
  • General cryptography on Solana

Please reach out!

  • Open an issue
  • Submit a PR

๐Ÿ“š References


๐Ÿ“„ License

MIT


Built with โค๏ธ and a mass amount of syscall abuse

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages