Skip to main content
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