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", ð])?;
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.
