Join our community of builders on

Telegram!Telegram
Utilities

Cryptography Utilities

Source Code

Overview

The Cryptography Utilities provide a set of cryptographic tools for Soroban smart contracts, including hash functions, Merkle tree verification, and Merkle-based distribution systems. These utilities enable secure data verification and efficient token distribution mechanisms. The Cryptography Utilities consist of two main packages:

  • Crypto: A set of cryptographic primitives and utilities for Soroban contracts.
  • Merkle Distributor: A system for distributing tokens or other assets using Merkle proofs for verification.

Crypto Package

The crypto package provides fundamental cryptographic primitives and utilities for Soroban contracts, with a focus on hashing and Merkle tree operations.

Key Components

Hashers

Provides a generic Hasher trait and implementations for common hash functions:

  • Sha256: Implementation of the SHA-256 hash function
  • Keccak256: Implementation of the Keccak-256 hash function (used in Ethereum)

Each hasher follows the same interface:

pub trait Hasher {
    type Output;

    fn new(e: &Env) -> Self;
    fn update(&mut self, input: Bytes);
    fn finalize(self) -> Self::Output;
}

Hashable

The Hashable trait allows types to be hashed with any Hasher implementation:

pub trait Hashable {
    fn hash<H: Hasher>(&self, hasher: &mut H);
}

Built-in implementations are provided for BytesN<32> and Bytes.

Utility Functions

  • hash_pair: Hashes two values together
  • commutative_hash_pair: Hashes two values in a deterministic order (important for Merkle trees)

Merkle Tree Verification

The Verifier struct provides functionality to verify Merkle proofs:

impl<H> Verifier<H>
where
    H: Hasher<Output = Bytes32>,
{
    pub fn verify(e: &Env, proof: Vec<Bytes32>, root: Bytes32, leaf: Bytes32) -> bool {
        // Implementation verifies that the leaf is part of the tree defined by root
    }
}

Usage Examples

Hashing Data

use soroban_sdk::{Bytes, Env};
use stellar_contract_utils::crypto::keccak::Keccak256;
use stellar_contract_utils::crypto::hasher::Hasher;

// Hash some data with Keccak256
let e = Env::default();
let data = Bytes::from_slice(&e, "Hello, world!".as_bytes());

let mut hasher = Keccak256::new(&e);
hasher.update(data);
let hash = hasher.finalize();

Verifying a Merkle Proof

use soroban_sdk::{BytesN, Env, Vec};
use stellar_crypto::keccak::Keccak256;
use stellar_crypto::merkle::Verifier;

// Verify that a leaf is part of a Merkle tree
let e = Env::default();
let root = /* merkle root as BytesN<32> */;
let leaf = /* leaf to verify as BytesN<32> */;
let proof = /* proof as Vec<BytesN<32>> */;

let is_valid = Verifier::<Keccak256>::verify(&e, proof, root, leaf);