The crypto module provides access to cryptographic functions including secure hash functions, signature verification, and elliptic curve operations.
Overview
Access cryptographic functions through env.crypto() in your contracts. The module provides both safe high-level functions and low-level hazmat functions for advanced use cases.
Types
Hash<N>
A BytesN<N> that is guaranteed to be generated by a cryptographic hash function.
pub struct Hash<const N: usize>(BytesN<N>);
Methods:
to_bytes() -> BytesN<N> - Returns the hash as a BytesN
to_array() -> [u8; N] - Returns the hash as a byte array
Note: Hash should not be used with storage since there’s no guarantee stored bytes came from a secure hash function.
Crypto
Provides access to cryptographic functions.
pub struct Crypto {
// ...
}
Functions
Hashing
sha256
Computes the SHA-256 hash of data.
pub fn sha256(&self, data: &Bytes) -> Hash<32>
Example:
use soroban_sdk::{Env, Bytes};
fn example(env: Env, data: Bytes) {
let hash = env.crypto().sha256(&data);
// hash is a Hash<32>
}
keccak256
Computes the Keccak-256 hash of data.
pub fn keccak256(&self, data: &Bytes) -> Hash<32>
Example:
use soroban_sdk::{Env, Bytes};
fn example(env: Env, data: Bytes) {
let hash = env.crypto().keccak256(&data);
}
Signature Verification
ed25519_verify
Verifies an Ed25519 signature.
pub fn ed25519_verify(
&self,
public_key: &BytesN<32>,
message: &Bytes,
signature: &BytesN<64>
)
Parameters:
public_key - 32-byte Ed25519 public key
message - The message that was signed
signature - 64-byte signature to verify
Panics: If signature verification fails.
Example:
use soroban_sdk::{Env, Bytes, BytesN};
fn verify(env: Env, pubkey: BytesN<32>, msg: Bytes, sig: BytesN<64>) {
env.crypto().ed25519_verify(&pubkey, &msg, &sig);
// Execution continues only if signature is valid
}
secp256k1_recover
Recovers the ECDSA secp256k1 public key from a signature.
pub fn secp256k1_recover(
&self,
message_digest: &Hash<32>,
signature: &BytesN<64>,
recovery_id: u32
) -> BytesN<65>
Parameters:
message_digest - 32-byte hash of the message (must be from a secure hash)
signature - 64-byte ECDSA signature
recovery_id - Recovery ID (0-3)
Returns: SEC-1-encoded 65-byte public key
Example:
use soroban_sdk::{Env, BytesN};
use soroban_sdk::crypto::Hash;
fn recover(env: Env, hash: Hash<32>, sig: BytesN<64>) {
let pubkey = env.crypto().secp256k1_recover(&hash, &sig, 0);
// pubkey is a BytesN<65>
}
secp256r1_verify
Verifies an ECDSA secp256r1 signature.
pub fn secp256r1_verify(
&self,
public_key: &BytesN<65>,
message_digest: &Hash<32>,
signature: &BytesN<64>
)
Parameters:
public_key - 65-byte SEC-1-encoded public key
message_digest - 32-byte hash of the message
signature - 64-byte signature
Elliptic Curves
bls12_381
Accesses BLS12-381 curve operations.
pub fn bls12_381(&self) -> bls12_381::Bls12_381
bn254
Accesses BN254 curve operations.
pub fn bn254(&self) -> bn254::Bn254
Hazmat Functions
Hazardous Materials: Functions in CryptoHazmat are low-level and can be insecure if misused. Use the high-level Crypto functions when possible.
The CryptoHazmat struct provides low-level cryptographic functions:
secp256k1_recover (hazmat)
Same as Crypto::secp256k1_recover but accepts a BytesN<32> instead of Hash<32>.
Warning: The message digest must be produced by a secure cryptographic hash function, otherwise attackers can potentially forge signatures.
secp256r1_verify (hazmat)
Same as Crypto::secp256r1_verify but accepts a BytesN<32> instead of Hash<32>.
Warning: The message digest must be produced by a secure cryptographic hash function.
poseidon_permutation
Performs a Poseidon permutation on the input state vector.
pub fn poseidon_permutation(
&self,
input: &Vec<U256>,
field: Symbol,
t: u32,
d: u32,
rounds_f: u32,
rounds_p: u32,
mds: &Vec<Vec<U256>>,
round_constants: &Vec<Vec<U256>>
) -> Vec<U256>
Warning: This is a low-level permutation. Most users should use higher-level hash functions.
poseidon2_permutation
Performs a Poseidon2 permutation on the input state vector.
pub fn poseidon2_permutation(
&self,
input: &Vec<U256>,
field: Symbol,
t: u32,
d: u32,
rounds_f: u32,
rounds_p: u32,
mat_internal_diag_m_1: &Vec<U256>,
round_constants: &Vec<Vec<U256>>
) -> Vec<U256>
Example
use soroban_sdk::{contract, contractimpl, Env, Bytes, BytesN};
#[contract]
pub struct Contract;
#[contractimpl]
impl Contract {
pub fn verify_signature(
env: Env,
public_key: BytesN<32>,
message: Bytes,
signature: BytesN<64>
) -> bool {
// Hash the message
let hash = env.crypto().sha256(&message);
// Verify the signature
env.crypto().ed25519_verify(&public_key, &message, &signature);
true
}
}
See Also
- auth - For custom account authorization
- Bytes - For byte arrays and fixed-size BytesN