|
| 1 | +--- |
| 2 | +title: Cryptography Utilities |
| 3 | +--- |
| 4 | + |
| 5 | +[Source Code](https://github.com/OpenZeppelin/stellar-contracts/tree/main/packages/contract-utils/src/crypto) |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +The Cryptography Utilities provide a set of cryptographic tools for Soroban smart contracts, |
| 10 | +including hash functions, Merkle tree verification, and Merkle-based distribution systems. |
| 11 | +These utilities enable secure data verification and efficient token distribution mechanisms. |
| 12 | +The Cryptography Utilities consist of two main packages: |
| 13 | + |
| 14 | +* Crypto: A set of cryptographic primitives and utilities for Soroban contracts. |
| 15 | +* [Merkle Distributor](./merkle-distributor): A system for distributing tokens or other assets using Merkle proofs for verification. |
| 16 | + |
| 17 | +## Crypto Package |
| 18 | + |
| 19 | +The crypto package provides fundamental cryptographic primitives and utilities for Soroban contracts, |
| 20 | +with a focus on hashing and Merkle tree operations. |
| 21 | + |
| 22 | +### Key Components |
| 23 | + |
| 24 | +#### Hashers |
| 25 | + |
| 26 | +Provides a generic `Hasher` trait and implementations for common hash functions: |
| 27 | + |
| 28 | +* `Sha256`: Implementation of the SHA-256 hash function |
| 29 | +* `Keccak256`: Implementation of the Keccak-256 hash function (used in Ethereum) |
| 30 | + |
| 31 | +Each hasher follows the same interface: |
| 32 | + |
| 33 | +```rust |
| 34 | +pub trait Hasher { |
| 35 | + type Output; |
| 36 | + |
| 37 | + fn new(e: &Env) -> Self; |
| 38 | + fn update(&mut self, input: Bytes); |
| 39 | + fn finalize(self) -> Self::Output; |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +#### Hashable |
| 44 | + |
| 45 | +The `Hashable` trait allows types to be hashed with any `Hasher` implementation: |
| 46 | + |
| 47 | +```rust |
| 48 | +pub trait Hashable { |
| 49 | + fn hash<H: Hasher>(&self, hasher: &mut H); |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +Built-in implementations are provided for `BytesN<32>` and `Bytes`. |
| 54 | + |
| 55 | +#### Utility Functions |
| 56 | + |
| 57 | +* `hash_pair`: Hashes two values together |
| 58 | +* `commutative_hash_pair`: Hashes two values in a deterministic order (important for Merkle trees) |
| 59 | + |
| 60 | +#### Merkle Tree Verification |
| 61 | + |
| 62 | +The `Verifier` struct provides functionality to verify Merkle proofs: |
| 63 | + |
| 64 | +```rust |
| 65 | +impl<H> Verifier<H> |
| 66 | +where |
| 67 | + H: Hasher<Output = Bytes32>, |
| 68 | +{ |
| 69 | + pub fn verify(e: &Env, proof: Vec<Bytes32>, root: Bytes32, leaf: Bytes32) -> bool { |
| 70 | + // Implementation verifies that the leaf is part of the tree defined by root |
| 71 | + } |
| 72 | +} |
| 73 | +``` |
| 74 | + |
| 75 | +### Usage Examples |
| 76 | + |
| 77 | +#### Hashing Data |
| 78 | + |
| 79 | +```rust |
| 80 | +use soroban_sdk::{Bytes, Env}; |
| 81 | +use stellar_contract_utils::crypto::keccak::Keccak256; |
| 82 | +use stellar_contract_utils::crypto::hasher::Hasher; |
| 83 | + |
| 84 | +// Hash some data with Keccak256 |
| 85 | +let e = Env::default(); |
| 86 | +let data = Bytes::from_slice(&e, "Hello, world!".as_bytes()); |
| 87 | + |
| 88 | +let mut hasher = Keccak256::new(&e); |
| 89 | +hasher.update(data); |
| 90 | +let hash = hasher.finalize(); |
| 91 | +``` |
| 92 | + |
| 93 | +#### Verifying a Merkle Proof |
| 94 | + |
| 95 | +```rust |
| 96 | +use soroban_sdk::{BytesN, Env, Vec}; |
| 97 | +use stellar_crypto::keccak::Keccak256; |
| 98 | +use stellar_crypto::merkle::Verifier; |
| 99 | + |
| 100 | +// Verify that a leaf is part of a Merkle tree |
| 101 | +let e = Env::default(); |
| 102 | +let root = /* merkle root as BytesN<32> */; |
| 103 | +let leaf = /* leaf to verify as BytesN<32> */; |
| 104 | +let proof = /* proof as Vec<BytesN<32>> */; |
| 105 | + |
| 106 | +let is_valid = Verifier::<Keccak256>::verify(&e, proof, root, leaf); |
| 107 | +``` |
| 108 | + |
| 109 | + |
0 commit comments