Using Crypto on Guest and Host
airbender-crypto provides cryptographic primitives that work on both host and guest. When using airbender-sdk with the crypto feature, delegation backends are enabled automatically. If you depend on airbender-crypto directly, you need to enable the proving feature for delegated implementations — otherwise primitives fall back to their naive software versions.
Add Dependency
The recommended approach is through the SDK:
[dependencies]
airbender = { package = "airbender-sdk", features = ["std", "crypto"] }
For direct usage with more fine-grained control over features:
[dependencies]
airbender-crypto = { path = "../../crates/airbender-crypto", features = ["proving"] }
Or via the SDK re-export (always enables delegation):
[dependencies]
airbender = { package = "airbender-sdk", path = "../../crates/airbender-sdk", features = ["crypto"] }
Then import from airbender::crypto.
Available Primitives
- Hashing:
sha256,sha3(Keccak256),ripemd160,blake2s - Curves:
k256,p256(re-exports),secp256k1,secp256r1(Airbender-specific helpers) - Pairing/field:
bn254,bls12_381
Example
#![allow(unused)] fn main() { use airbender_crypto::sha3::Keccak256; use airbender_crypto::MiniDigest; pub fn hash32(data: &[u8]) -> [u8; 32] { Keccak256::digest(data) } }
MiniDigest is a simplified digest trait that returns a fixed [u8; 32]. This code works identically on host and guest. On the guest with proving enabled, Keccak256 routes through a delegated backend that’s dramatically cheaper to prove.
Why Delegation Matters
On RISC-V guests, crypto operations are expensive to prove because every instruction becomes part of the execution trace. Delegated backends move heavy arithmetic to VM-specific circuits that the prover handles natively.
In practice:
- Lower proving cost for crypto-heavy guest logic
- Same code on host and guest. Backend selection happens via target and features.
- Transparent. You don’t need to change your API calls.
Prefer delegated primitives when they’re available. They can be orders of magnitude cheaper on the guest.
Delegation Status
Delegated (use these when possible):
sha3(Keccak256) - viakeccak_special5blake2s(Blake2s256) - viasingle_round_with_controlsecp256k1field/scalar - viabigint_opssecp256r1field/scalar - viabigint_opsbn254base/extension field and curve arithmetic (delegatedFq;Fruses arkworks)bls12_381field and curve arithmetic (Fq,Fr, and extension fields)
Also available, without delegation (software-only, higher proving cost):
sha256ripemd160k256p256
Secp256k1 Hooks
EC recovery (ecrecover) involves three expensive operations: a field-element square root to decompress the public key, a field-element inversion to convert from Jacobian to affine coordinates, and a scalar inversion for the recovery formula. On a RISC-V guest these dominate the proving cost of every ecrecover call.
The Secp256k1Hooks trait lets you replace these three operations with your own implementation. The primary use case is hint-and-verify: the host precomputes the result and passes it as a hint, and the guest checks it with a single multiplication (a * a⁻¹ == 1) instead of recomputing from scratch. This is much cheaper to prove.
Using custom hooks
Most callers should use the standard secp256k1::recover API, which computes everything directly.
To make use of hooks, implement Secp256k1Hooks and pass them to secp256k1::recover_with_hooks.
Each trait method receives a mutable reference to the value that needs the operation and should store the result in-place. For inversions, verify with candidate * input == 1. For square roots, verify with candidate² == input.
The _with_hooks variants are also available on the lower-level operations:
Affine::decompress_with_hooks— point decompression (usesfe_sqrt_and_assign)Jacobian::to_affine_with_hooks— coordinate conversion (usesfe_invert_and_assign)recover_with_context_and_hooks— recovery with explicit precomputed context
Hook implementations must produce correct results. The recovery functions trust the hook output and do not re-verify it. The verification logic belongs in the hook implementation itself.
Example
The examples/ecrecover-hooks/ example demonstrates the full hint-and-verify flow: the host precomputes hints with CapturingHooks, the guest verifies them cheaply with PrecomputedHintHooks.
Practical Tips
- Write shared crypto code that runs on both host and guest. Test on the host first (faster iteration), then run guest execution/proof flows.
- For secp usage examples, see the crate tests: