Skip to content
hopper
Get started
Model / crypto-capabilities

Crypto capabilities

SHA-256, Keccak, BLAKE3, precompile checks, secp recovery, and the remaining heavy-crypto roadmap.

Hopper's crypto surface is Solana-shaped: no-alloc wrappers around runtime syscalls, plus strict helpers for native precompile instructions. The framework does not drag a general-purpose crypto library into every program. It exposes the cryptography Solana already verifies and makes the bytes easy to audit.

Current coverage

Primitive Hopper API Solana mechanism Status
SHA-256 hopper::crypto::sha256, sha256_single sol_sha256 / backend hasher Shipped
Keccak-256 hopper::crypto::keccak256, keccak256_single sol_keccak256 / backend hasher Shipped
BLAKE3 hopper::crypto::blake3, blake3_single sol_blake3 Shipped
Curve point validation hopper::crypto::curve_validate_point, curve25519_edwards_validate_point sol_curve_validate_point Shipped
Ed25519 precompile check_ed25519_signature_at, check_ed25519_signer_at Ed25519 program + instructions sysvar Shipped
Secp256k1 precompile check_secp256k1_instruction_at, check_secp256k1_instruction_at_cross_instruction secp256k1 native program + instructions sysvar Shipped
Secp256k1 recover secp256k1_recover, recover_ethereum_address sol_secp256k1_recover Shipped on-chain
Merkle inclusion hopper_solana::crypto::merkle SHA-256 helper Shipped
Curve group operations curve_group_add, curve_group_sub, curve_group_mul, curve_multiscalar_mul sol_curve_group_op, sol_curve_multiscalar_mul Shipped behind crypto-curve
Poseidon poseidon_hashv, poseidon_hash, poseidon_bn254_x5 sol_poseidon Shipped behind crypto-poseidon
alt_bn128 / BN254 alt_bn128_add, alt_bn128_mul, alt_bn128_pairing, compression helpers sol_alt_bn128_group_op, sol_alt_bn128_compression Shipped behind crypto-bn254
Big modular exponentiation big_mod_exp sol_big_mod_exp Shipped behind crypto-big-mod-exp

Host tests that need real digest bytes should use a software hasher in the test crate. Hopper's on-chain helpers stay dependency-light and route through the active Solana backend.

Hash helpers

use hopper::crypto::{blake3, keccak256, sha256};

let domain = b"hopper:v1:auth";
let user = user_key.as_ref();

let sha = sha256(&[domain, user])?;
let eth = keccak256(&[b"\x19Ethereum Signed Message:\n32", &sha])?;
let compact = blake3(&[b"receipt", &eth])?;

Hopper rejects more than 16 hash segments instead of silently dropping tail segments. Hash APIs must never ignore bytes.

Ed25519 precompile checks

use hopper::crypto::check_ed25519_signature_at;

check_ed25519_signature_at(
    instructions_sysvar_data,
    ed25519_ix_index,
    0,
    expected_signer,
    expected_message,
)?;

The runtime verifies the signature. Hopper verifies that the verified payload is the signer and message your program intended, including selected-signature indexing and offset bounds.

Secp256k1 precompile checks

use hopper::crypto::check_secp256k1_instruction_at;

check_secp256k1_instruction_at(
    instructions_sysvar_data,
    secp_ix_index,
    0,
    expected_eth_address,
    expected_message,
)?;

The strict checker only accepts signature, recovery id, Ethereum address, and message bytes stored in the secp256k1 instruction itself. If a protocol deliberately stores those bytes in another transaction instruction, use the cross-instruction variant so that choice is explicit:

use hopper::crypto::check_secp256k1_instruction_at_cross_instruction;

check_secp256k1_instruction_at_cross_instruction(
    instructions_sysvar_data,
    secp_ix_index,
    signature_index,
    expected_eth_address,
    expected_message,
)?;

Secp256k1 recover

use hopper::crypto::{recover_ethereum_address, secp256k1_recover};

let pubkey64 = secp256k1_recover(message_hash, recovery_id, signature)?;
let eth_address = recover_ethereum_address(message_hash, recovery_id, signature)?;

Prefer the precompile checker when the transaction can include a native secp256k1 verification instruction, especially for batches. Reach for recovery when the protocol truly needs the recovered key in-program.

Feature-gated heavy crypto

The heavy-crypto surface is feature-gated so tiny programs do not pay for APIs they never call.

Feature API family
crypto-curve curve group add/sub/mul and multiscalar wrappers
crypto-poseidon Poseidon hash wrappers
crypto-bn254 alt_bn128 add/mul/pairing wrappers
crypto-big-mod-exp bounded big modular exponentiation wrappers

The wrappers deliberately expose Solana's byte-level contracts. BN254 helpers use the same operation ids and byte lengths as Solana's solana-bn254 crate; Poseidon accepts 1 to 12 32-byte inputs; curve multiplication passes the scalar as the left operand and point as the right operand, matching Solana's syscall ABI. Big modular exponentiation writes into a caller-provided output buffer whose length must match the modulus length.

SBF tests remain the next hardening lane before treating the heavy crypto path as fully exercised across validator versions.