### Install Coverage Dependencies Source: https://github.com/facebook/akd/blob/main/xtask/README.md Run these commands once to install the required llvm-tools and grcov utility. ```bash rustup component add llvm-tools-preview cargo install grcov ``` -------------------------------- ### Complete Value Commitment Example Source: https://github.com/facebook/akd/blob/main/_autodocs/10-protocol-specifications.md Provides a complete example of calculating commitment_nonce, commitment, and azks_value with sample parameters. ```rust value = "public_key_bytes" commitment_key = (derived from vsk) node_label = (computed above) version = 1 epoch = 1 commitment_nonce = Hash(commitment_key || node_label || 0x0000000000000001 || 0x00000010 || value) commitment = Hash(0x00000010 || value || 0x00000020 || commitment_nonce) azks_value = Hash(commitment || I2OSP(1)) ``` -------------------------------- ### In-Memory Database Usage Example Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md Demonstrates how to create an `AsyncInMemoryDatabase` and use it with a `StorageManager` and `Directory`. ```rust use akd::storage::memory::AsyncInMemoryDatabase; use akd::storage::StorageManager; // Create in-memory storage let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); // Use with Directory let dir = Directory::new(storage, vrf, config).await?; ``` -------------------------------- ### ExperimentalConfiguration Usage Example Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md Shows how to use ExperimentalConfiguration for directory initialization, featuring domain separation for hashing. ```rust use akd::ExperimentalConfiguration; type Config = ExperimentalConfiguration; let dir = Directory::::new(storage, vrf, config).await?; ``` -------------------------------- ### Custom Storage Implementation Example Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md An example of implementing the `Database` trait for a custom storage solution using a HashMap. This includes basic implementations for set, batch_set, get, batch_get, and user-specific data retrieval methods. ```rust use akd::storage::{Database, Storable, StorageError, DbRecord, DbSetState}; use async_trait::async_trait; use std::collections::HashMap; pub struct MyDatabase { data: HashMap, DbRecord>, } #[async_trait] impl Database for MyDatabase { async fn set(&self, record: DbRecord) -> Result<(), StorageError> { // Implementation Ok(()) } async fn batch_set( &self, records: Vec, state: DbSetState, ) -> Result<(), StorageError> { // Implementation Ok(()) } async fn get(&self, id: &St::StorageKey) -> Result { // Implementation Err(StorageError::NotFound("Not implemented".to_string())) } async fn batch_get( &self, ids: &[St::StorageKey], ) -> Result, StorageError> { // Implementation Ok(vec![]) } async fn get_user_data(&self, username: &AkdLabel) -> Result { // Implementation Err(StorageError::NotFound("Not implemented".to_string())) } async fn get_user_state( &self, username: &AkdLabel, flag: ValueStateRetrievalFlag, ) -> Result { // Implementation Err(StorageError::NotFound("Not implemented".to_string())) } async fn get_user_state_versions( &self, usernames: &[AkdLabel], flag: ValueStateRetrievalFlag, ) -> Result, StorageError> { // Implementation Ok(HashMap::new()) } } ``` -------------------------------- ### Node Label Computation Example Source: https://github.com/facebook/akd/blob/main/_autodocs/10-protocol-specifications.md Illustrates the computation of vrf_input and node_label using specific example values for label, freshness, and version. ```rust label = "alice" freshness = Fresh (0x01) version = 1 Hash input = [00 00 00 00 00 00 00 05] || [61 6c 69 63 65] || [01] || [00 00 00 00 00 00 00 01] = 0x0000000005616c696365010000000000000001 vrf_input = Hash(0x0000000005616c696365010000000000000001) = 32-byte digest node_label = VRF(vsk, vrf_input) // Produces 256-bit NodeLabel ``` -------------------------------- ### Run MySQL Demo Benchmark Source: https://github.com/facebook/akd/blob/main/examples/README.md Example command to run a benchmark publish operation with specified users and epochs. ```bash cargo run -p examples --release -- mysql-demo bench-publish 1000 3 ``` -------------------------------- ### VRFPublicKey Usage Example Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md Demonstrates how to retrieve a public key, convert it to bytes, and reconstruct it for client use. ```rust use akd::ecvrf::VRFPublicKey; let public_key = dir.get_public_key().await?; let bytes = public_key.as_bytes(); // Distribute to clients let client_key = VRFPublicKey::from_bytes(bytes)?; ``` -------------------------------- ### HardCodedAkdVRF Example Usage Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md Shows how to instantiate and use the HardCodedAkdVRF for testing purposes. ```rust use akd::ecvrf::HardCodedAkdVRF; // For testing/development only let vrf = HardCodedAkdVRF; let dir = Directory::new(storage, vrf, config).await?; ``` -------------------------------- ### Protocol Versioning Example Source: https://github.com/facebook/akd/blob/main/_autodocs/10-protocol-specifications.md Illustrates the progression of label versions and global epochs during publish operations. ```plaintext Epoch 1: Publish (alice, key1), (bob, key2) alice version=1, bob version=1 Epoch 2: Publish (alice, key1'), (charlie, key3) alice version=2, bob version=1 (unchanged), charlie version=1 Epoch 3: Publish (bob, key2') alice version=2 (unchanged), bob version=2, charlie version=1 (unchanged) ``` -------------------------------- ### WhatsAppV1Configuration Usage Example Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md Demonstrates how to use WhatsAppV1Configuration for directory initialization, compatible with WhatsApp's key transparency deployment. ```rust use akd::WhatsAppV1Configuration; type Config = WhatsAppV1Configuration; let dir = Directory::::new(storage, vrf, config).await?; ``` -------------------------------- ### Basic AKD Directory Setup Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Demonstrates how to initialize the AKD directory with an in-memory storage backend and a hardcoded VRF provider. Ensure necessary imports are included. ```rust use akd::{ directory::Directory, storage::{StorageManager, memory::AsyncInMemoryDatabase}, ecvrf::HardCodedAkdVRF, append_only_zks::AzksParallelismConfig, WhatsAppV1Configuration, }; #[tokio::main] async fn main() -> Result<(), Box> { // 1. Create storage backend let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); // 2. Create VRF provider let vrf = HardCodedAkdVRF {}; // 3. Create directory with configuration type Config = WhatsAppV1Configuration; let dir = Directory::::new( storage, vrf, AzksParallelismConfig::default(), ).await?; // 4. Directory is ready to use Ok(()) } ``` -------------------------------- ### Start MySQL container with Docker Compose Source: https://github.com/facebook/akd/blob/main/CONTRIBUTING.md Commands to navigate to the repository root and launch the MySQL container environment. ```bash cd docker compose up [-d] ``` -------------------------------- ### Start Transaction Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md Initiates a new transaction. Returns `false` if a transaction is already in progress. ```rust pub fn begin_transaction(&self) -> bool ``` -------------------------------- ### HistoryParams Usage Examples Source: https://github.com/facebook/akd/blob/main/_autodocs/03-types-and-data-structures.md Demonstrates how to instantiate HistoryParams for complete history or a specific number of recent versions. ```rust use akd::HistoryParams; // Get all versions let params = HistoryParams::Complete; // Get only last 5 versions let params = HistoryParams::MostRecent(5); ``` -------------------------------- ### Minimal AKD Publish and Lookup Example Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Demonstrates the basic usage of AKD for publishing a key-value pair and performing a lookup to retrieve a proof. Requires the `tokio` runtime. ```rust use akd::{ directory::Directory, storage::{StorageManager, memory::AsyncInMemoryDatabase}, ecvrf::HardCodedAkdVRF, append_only_zks::AzksParallelismConfig, WhatsAppV1Configuration, AkdLabel, AkdValue, }; #[tokio::main] async fn main() -> Result<(), Box> { type Config = WhatsAppV1Configuration; let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); let vrf = HardCodedAkdVRF {}; let dir = Directory::::new( storage, vrf, AzksParallelismConfig::default(), ).await?; // Publish let EpochHash(epoch, root_hash) = dir.publish(vec![ (AkdLabel::from("alice"), AkdValue::from("public_key")), ]).await?; println!("Published to epoch {}", epoch); // Lookup let (proof, epoch_hash) = dir.lookup(AkdLabel::from("alice")).await?; println!("Got proof at epoch {}", epoch_hash.epoch()); Ok(()) } ``` -------------------------------- ### Custom Storage Implementation Example Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Illustrates how to implement the `Database` trait for custom storage backends. This is necessary for integrating AKD with different database systems. ```rust #[async_trait] impl Database for MyDatabase { async fn set(&self, record: DbRecord) -> Result<(), StorageError> { /* ... */ } async fn batch_set(&self, records: Vec, state: DbSetState) -> Result<(), StorageError> { /* ... */ } async fn get(&self, id: &St::StorageKey) -> Result { /* ... */ } // ... other methods } ``` -------------------------------- ### Complete AKD Verification Flow Example Source: https://github.com/facebook/akd/blob/main/_autodocs/02-client-verification.md Illustrates a full client-side verification process, including lookup, history, and audit verification. ```rust use akd::{AkdLabel, client, WhatsAppV1Configuration, HistoryVerificationParams}; type Config = WhatsAppV1Configuration; // 1. Client receives epoch hash and proofs from server let (lookup_proof, epoch_hash) = server.lookup(AkdLabel::from("alice")).await?; // 2. Verify lookup proof let lookup_result = client::lookup_verify::( public_key.as_bytes(), epoch_hash.hash(), epoch_hash.epoch(), AkdLabel::from("alice"), lookup_proof, )?; println!("Alice's key: {:?}", lookup_result.value); // 3. Request and verify history let (history_proof, _) = server.key_history( &AkdLabel::from("alice"), Default::default(), ).await?; let history = client::key_history_verify::( public_key.as_bytes(), epoch_hash.hash(), epoch_hash.epoch(), AkdLabel::from("alice"), history_proof, HistoryVerificationParams::default(), )?; for result in history { println!("Version {}: {} (epoch {})", result.version, String::from_utf8_lossy(&result.value), result.epoch); } // 4. Verify audit for consistency let audit_proof = server.audit(epoch1, epoch2).await?; akd::auditor::audit_verify::( vec![hash1, hash2], audit_proof, ).await?; println!("All verifications passed!"); ``` -------------------------------- ### HistoryVerificationParams Usage Examples Source: https://github.com/facebook/akd/blob/main/_autodocs/02-client-verification.md Demonstrates how to instantiate HistoryVerificationParams for different verification needs. ```rust // Default: strict validation let params = HistoryVerificationParams::default(); // Allow tombstoned values (useful when checking existence without caring about value) let params = HistoryVerificationParams::AllowMissingValues(None); ``` -------------------------------- ### AzksParallelismConfig Usage Examples Source: https://github.com/facebook/akd/blob/main/_autodocs/03-types-and-data-structures.md Shows how to configure parallelism for AKD operations. Includes default, disabled, and fixed parallelism settings. ```rust use akd::append_only_zks::{AzksParallelismConfig, AzksParallelismOption}; // Use system default (auto-detect cores) let config = AzksParallelismConfig::default(); // Disable parallelism let config = AzksParallelismConfig::disabled(); // Fixed parallelism let config = AzksParallelismConfig { insertion: AzksParallelismOption::Static(8), preload: AzksParallelismOption::Static(8), }; ``` -------------------------------- ### Install AKD Dependency Source: https://github.com/facebook/akd/blob/main/README.md Add this line to the dependencies section of your Cargo.toml file to include the AKD library. ```toml akd = "0.12.0" ``` -------------------------------- ### I2OSP Encoding Examples Source: https://github.com/facebook/akd/blob/main/_autodocs/10-protocol-specifications.md Demonstrates the output of the I2OSP primitive for specific integer inputs, showing big-endian byte representation. ```rust // Examples: I2OSP(1) = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01] I2OSP(256) = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00] ``` -------------------------------- ### Production VRFKeyStorage Implementation Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md An example implementation of a secure VRF key storage using asynchronous operations, simulating loading and decrypting keys from a secure path. ```rust use akd::ecvrf::VRFKeyStorage; use async_trait::async_trait; pub struct ProductionVrfStorage { private_key_path: String, // Could use HSM, KMS, encrypted file, etc. } #[async_trait] impl VRFKeyStorage for ProductionVrfStorage { async fn retrieve(&self) -> Result, akd::ecvrf::VrfError> { // 1. Load encrypted key from secure storage // 2. Decrypt using HSM or KMS // 3. Return 32-byte ed25519 seed // 4. Never log or expose the key // Example (oversimplified): let encrypted_key = tokio::fs::read(&self.private_key_path).await .map_err(|e| akd::ecvrf::VrfError::InvalidKey(e.to_string()))?; let decrypted = decrypt_with_hsm(&encrypted_key).await?; Ok(decrypted) } } #[async_trait] impl Clone for ProductionVrfStorage { fn clone(&self) -> Self { // Share reference to storage, not the key Self { private_key_path: self.private_key_path.clone(), } } } ``` -------------------------------- ### AkdError Usage Example Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Demonstrates how to match and handle different AkdError variants during operations like directory lookups. ```rust use akd::AkdError; match dir.lookup(label).await { Ok((proof, epoch_hash)) => { /* ... */ }, Err(AkdError::Storage(e)) => eprintln!("Storage error: {}", e), Err(AkdError::Vrf(e)) => eprintln!("VRF error: {}", e), Err(e) => eprintln!("Other error: {}", e), } ``` -------------------------------- ### DirectoryError Handling Example Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Illustrates how to handle specific DirectoryError variants, like 'Publish' for duplicate labels or 'InvalidEpoch', when publishing updates. ```rust use akd::errors::{AkdError, DirectoryError}; match dir.publish(updates).await { Ok(epoch_hash) => println!("Published to epoch {}", epoch_hash.epoch()), Err(AkdError::Directory(DirectoryError::Publish(msg))) => { eprintln!("Invalid publish: {}", msg); // Check for duplicate labels }, Err(AkdError::Directory(DirectoryError::InvalidEpoch(msg))) => { eprintln!("Epoch error: {}", msg); // Use valid epoch range }, Err(e) => eprintln!("Unexpected error: {}", e), } ``` -------------------------------- ### Rust Unit Test Example Source: https://github.com/facebook/akd/blob/main/TESTING.md Standard Rust unit test. Use `#[tokio::test]` for async functions. ```rust #[test] fn my_test() { panic!("boom"); } #[tokio::test] async fn my_async_test() { panic!("async boom!"); } ``` -------------------------------- ### Unit Test Publish and Lookup with In-Memory Storage Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Provides a unit test example demonstrating the basic functionality of publishing an entry and then looking it up using an in-memory database. This is a common pattern for testing AKD logic without external dependencies. ```rust #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_publish_and_lookup() -> Result<(), Box> { let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); let vrf = HardCodedAkdVRF {}; type Config = WhatsAppV1Configuration; let dir = Directory::::new( storage, vrf, AzksParallelismConfig::default(), ).await?; // Publish let entry = ( AkdLabel::from("alice"), AkdValue::from("key"), ); let EpochHash(epoch, _) = dir.publish(vec![entry]).await?; // Lookup let (proof, epoch_hash) = dir.lookup( AkdLabel::from("alice") ).await?; assert_eq!(epoch_hash.epoch(), epoch); Ok(()) } } ``` -------------------------------- ### Structured Logging with Slog Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Implement structured logging for production systems to capture detailed error information. This example shows how to log success and failure events with associated context. ```rust use slog::{error, warn, info}; match dir.publish(updates).await { Ok(epoch_hash) => { info!(logger, "Publish successful"; "epoch" => epoch_hash.epoch()); }, Err(e) => { error!(logger, "Publish failed"; "error" => format!("{}", e), "error_type" => format!("{:?}", e)); }, } ``` -------------------------------- ### Rust Test Module Setup Source: https://github.com/facebook/akd/blob/main/TESTING.md Organize tests by decorating a `test` or `tests` sub-module with `#[cfg(test)]`. This ensures the code is only included during test compilation. ```rust /// Global test startup constructor. Only runs in the TEST profile. Each /// crate which wants logging enabled in tests being run should make this call /// itself. #[cfg(test)] #[ctor::ctor] fn test_start() { init_logger(Level::Info); } ``` -------------------------------- ### Implement VRFKeyStorage for Production Key Management Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Implement the VRFKeyStorage trait for production key management, such as loading keys from HSM, KMS, or encrypted storage. This example shows how to retrieve a 32-byte ed25519 seed. ```rust #[async_trait] impl VRFKeyStorage for MyVrfStorage { async fn retrieve(&self) -> Result, VrfError> { // Load from HSM, KMS, encrypted storage, etc. // Return 32-byte ed25519 seed } } ``` -------------------------------- ### Interactive Mode for WhatsApp KT Auditor Source: https://github.com/facebook/akd/blob/main/examples/src/whatsapp_kt_auditor/README.md Launch the auditor in interactive mode to load all epochs and select which ones to audit. This provides a guided experience for exploring audit proofs. ```bash cargo run -p examples --release -- whatsapp-kt-auditor -i ``` -------------------------------- ### Audit Latest Epoch with WhatsApp KT Auditor Source: https://github.com/facebook/akd/blob/main/examples/src/whatsapp_kt_auditor/README.md Run the auditor to check the latest available epoch in the default (v2) log. Ensure the 'examples' package is built. ```bash cargo run -p examples --release -- whatsapp-kt-auditor -l ``` -------------------------------- ### Run POC application help Source: https://github.com/facebook/akd/blob/main/TESTING.md Displays the command-line options for the proof-of-concept REPL application. ```bash > cargo run -- --help ``` -------------------------------- ### Run MySQL Demo with Docker Source: https://github.com/facebook/akd/blob/main/examples/README.md Commands to initialize the MySQL instance via Docker and execute the demo application. ```bash docker compose up [-d] ``` ```bash cargo run -p examples --release -- mysql-demo ``` -------------------------------- ### Directory::new Source: https://github.com/facebook/akd/blob/main/_autodocs/01-directory-api.md Creates a new Directory instance. Initializes the AZKS data structure if it does not already exist in storage. ```APIDOC ## Directory::new ### Description Creates a new Directory instance. Initializes the AZKS data structure if it does not already exist in storage. ### Signature ```rust pub async fn new( storage: StorageManager, vrf: V, parallelism_config: AzksParallelismConfig, ) -> Result ``` ### Parameters #### Path Parameters - **storage** (StorageManager) - Required - Storage manager instance - **vrf** (V) - Required - VRF key storage implementation - **parallelism_config** (AzksParallelismConfig) - Required - Parallelization settings for tree operations ### Response #### Success Response - **Directory** - The newly created Directory instance #### Error Response - **AkdError::Storage(StorageError:: *)** - Storage initialization errors - **AkdError** - Other AkdError variants on AZKS creation failure ### Example ```rust use akd::directory::Directory; use akd::storage::StorageManager; use akd::storage::memory::AsyncInMemoryDatabase; use akd::ecvrf::HardCodedAkdVRF; use akd::append_only_zks::AzksParallelismConfig; type Config = akd::WhatsAppV1Configuration; let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); let vrf = HardCodedAkdVRF {}; let dir = Directory::::new(storage, vrf, AzksParallelismConfig::default()) .await .expect("Failed to create directory"); ``` ``` -------------------------------- ### NodeLabel Get Bit Operation Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Retrieves a specific bit (0 or 1) from a NodeLabel at a given index. ```rust let bit = label.get_bit(index: usize) -> bool; // 0 or 1 ``` -------------------------------- ### get Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md Retrieves a single record by key. Returns the record if found, otherwise throws StorageError::NotFound. ```APIDOC ## get ### Description Retrieves a single record by key. ### Method async fn ### Parameters #### Path Parameters - **id** (&St::StorageKey) - Required - Record identifier ### Returns Result ### Throws: - StorageError::NotFound - Record not found ``` -------------------------------- ### Get Current Epoch and Hash Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Retrieves and prints the current epoch number and the root hash of the state. ```rust async fn get_current_state( dir: &Directory, ) -> Result<(), Box> { let EpochHash(epoch, hash) = dir.get_epoch_hash().await?; println!("Current epoch: {}", epoch); println!("Root hash: {}", hex::encode(hash)); Ok(()) } ``` -------------------------------- ### Get Full History Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Retrieves the complete history for a given username. Requires the `akd::HistoryParams` enum. ```rust use akd::HistoryParams; async fn get_full_history( dir: &Directory, username: &str, ) -> Result> { let label = AkdLabel::from(username); let (proof, epoch_hash) = dir.key_history( &label, HistoryParams::Complete, ).await?; println!("Got complete history for {} at epoch {}", username, epoch_hash.epoch()); Ok(proof) } ``` -------------------------------- ### Enable ExperimentalConfiguration Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md Use this snippet to enable ExperimentalConfiguration with domain separation for hashing. Requires the blake3 crate. ```toml [dependencies] akd = { version = "0.12.0", features = ["experimental"] } ``` ```rust use akd::ExperimentalConfiguration; type Config = ExperimentalConfiguration; let dir = Directory::::new(storage, vrf, config).await?; ``` -------------------------------- ### Conditional compilation attribute Source: https://github.com/facebook/akd/blob/main/TESTING.md Example of a Rust attribute used to conditionally compile code based on feature flags. ```rust #[cfg(not(feature = "vrf"))] ``` -------------------------------- ### Create New Directory Instance Source: https://github.com/facebook/akd/blob/main/_autodocs/01-directory-api.md Initializes a new Directory instance. This function is used to set up the AKD data structure, potentially initializing it in storage if it doesn't exist. Requires storage manager, VRF implementation, and parallelism configuration. ```rust use akd::directory::Directory; use akd::storage::StorageManager; use akd::storage::memory::AsyncInMemoryDatabase; use akd::ecvrf::HardCodedAkdVRF; use akd::append_only_zks::AzksParallelismConfig; type Config = akd::WhatsAppV1Configuration; let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); let vrf = HardCodedAkdVRF {}; let dir = Directory::::new(storage, vrf, AzksParallelismConfig::default()) .await .expect("Failed to create directory"); ``` -------------------------------- ### Enable WhatsAppV1Configuration Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md Use this snippet to enable the WhatsAppV1Configuration implementation. Requires the blake3 crate. ```toml [dependencies] akd = { version = "0.12.0", features = ["whatsapp_v1"] } ``` ```rust use akd::WhatsAppV1Configuration; type Config = WhatsAppV1Configuration; let dir = Directory::::new(storage, vrf, config).await?; ``` -------------------------------- ### NodeLabel Get Prefix Operation Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Computes and returns a NodeLabel representing the prefix of the original label up to a specified depth. ```rust let prefix = label.get_prefix(depth: u32) -> NodeLabel; ``` -------------------------------- ### AsyncInMemoryDatabase Usage Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md Demonstrates how to create and use the in-memory database implementation for testing and development. ```APIDOC ## In-Memory Database Usage ```rust use akd::storage::memory::AsyncInMemoryDatabase; use akd::storage::StorageManager; // Create in-memory storage let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); // Use with Directory // let dir = Directory::new(storage, vrf, config).await?; ``` ``` -------------------------------- ### Get Recent History Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Retrieves a specified number of the most recent history entries for a username. Uses `HistoryParams::MostRecent`. ```rust async fn get_recent_history( dir: &Directory, username: &str, recent_count: usize, ) -> Result> { let label = AkdLabel::from(username); let (proof, _) = dir.key_history( &label, HistoryParams::MostRecent(recent_count), ).await?; Ok(proof) } ``` -------------------------------- ### Client API Overview Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Overview of the client-side API for verifying proofs and interacting with the directory. ```APIDOC ## Client API ### Description Provides functionality for clients to verify proofs generated by the server and interact with the directory. ### Methods - `client::lookup_verify(proof)`: Verify a lookup proof. - `client::key_history_verify(proof)`: Verify a key history proof. - `auditor::audit_verify(proof)`: Verify an audit proof. ``` -------------------------------- ### Directory Tree State After 3 Publish Epochs Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Visualizes the directory tree's state after three epochs, detailing the root hash and the status of entries like 'alice' and 'bob' across versions. ```text Epoch 1: Publish (alice, key1), (bob, key2) alice_label = VRF(vrf_key, Hash("alice", Fresh, 1)) bob_label = VRF(vrf_key, Hash("bob", Fresh, 1)) → Root hash: 0x1234... Epoch 2: Publish (alice, key1'), (charlie, key3) alice_label (v2) = VRF(vrf_key, Hash("alice", Fresh, 2)) alice_label_stale (v1) = Hash(0x00) charlie_label = VRF(vrf_key, Hash("charlie", Fresh, 1)) → Root hash: 0x5678... Epoch 3: Publish (bob, key2') bob_label (v2) = VRF(vrf_key, Hash("bob", Fresh, 2)) bob_label_stale (v1) = Hash(0x00) → Root hash: 0x9abc... Tree State: Root [epoch 1: 0x1234, epoch 2: 0x5678, epoch 3: 0x9abc] ├─ alice_v2 [epoch 2: ..., epoch 3: ...] ├─ alice_v1_stale [epoch 2: ...] ├─ bob_v2 [epoch 3: ...] ├─ bob_v1_stale [epoch 2: ...] └─ charlie_v1 [epoch 2: ...] ``` -------------------------------- ### Perform Batch Publish and Lookups Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Demonstrates an optimized workflow using batch operations for publishing multiple entries and performing multiple lookups simultaneously. This pattern can significantly improve performance for large datasets. ```rust async fn optimized_workflow( dir: &Directory, ) -> Result<(), Box> { // Batch publish let entries = vec![ (AkdLabel::from("alice"), AkdValue::from("key1")), (AkdLabel::from("bob"), AkdValue::from("key2")), (AkdLabel::from("charlie"), AkdValue::from("key3")), ]; let EpochHash(epoch, hash) = dir.publish(entries).await?; // Batch lookups let labels = vec![ AkdLabel::from("alice"), AkdLabel::from("bob"), AkdLabel::from("charlie"), ]; let (proofs, _) = dir.batch_lookup(&labels).await?; println!("Batch processed {} labels at epoch {}", proofs.len(), epoch); Ok(()) } ``` -------------------------------- ### MySQL connection configuration details Source: https://github.com/facebook/akd/blob/main/CONTRIBUTING.md Default connection parameters for the MySQL test container. ```text MySQL port opened on local machine: 8001 User: "root" Password: "example" Default database: "default" ``` -------------------------------- ### Implement DomainLabel for Custom Type Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md Provides an example implementation of the DomainLabel trait for a custom struct, defining a specific domain label for hashing. ```rust use akd::DomainLabel; struct MyApplicationDomain; impl DomainLabel for MyApplicationDomain { fn domain_label() -> &'static [u8] { b"my-application-v1" } } ``` -------------------------------- ### ExperimentalConfiguration Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md ExperimentalConfiguration offers the latest cryptographic settings with domain separation for hashing, allowing for custom domain labels via the DomainLabel trait. It also uses the BLAKE3 hash function. ```APIDOC ## ExperimentalConfiguration ### Description Latest configuration with domain separation for hashing. ### Requirements Requires the `experimental` feature. ### Hash Function Uses BLAKE3. ### Domain Separation Implementations can define custom domain labels via `DomainLabel` trait. ### Usage ```rust use akd::ExperimentalConfiguration; type Config = ExperimentalConfiguration; // Assuming storage, vrf, and config are defined elsewhere // let dir = Directory::::new(storage, vrf, config).await?; ``` ``` -------------------------------- ### Azks::get_append_only_proof Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Generates a proof that the tree evolved consistently from a start epoch to an end epoch. This is useful for auditing and verifying historical states. ```APIDOC ## Azks::get_append_only_proof ### Description Generates a proof that the tree evolved consistently from start_epoch to end_epoch. ### Method `async fn get_append_only_proof( &self, storage: &StorageManager, start_epoch: u64, end_epoch: u64, insert_mode: InsertMode, ) -> Result` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **storage** (`&StorageManager`) - Storage manager - **start_epoch** (`u64`) - The starting epoch for the proof - **end_epoch** (`u64`) - The ending epoch for the proof - **insert_mode** (`InsertMode`) - Directory or Auditor mode ### Request Example None ### Response #### Success Response (200) - **AppendOnlyProof** (The generated append-only proof) - **AkdError** (Error type) #### Response Example None ``` -------------------------------- ### VRFPublicKey Structure Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md A wrapper for VRF public keys designed for client distribution. Provides methods to get raw bytes and reconstruct from bytes. ```rust pub struct VRFPublicKey { // Internal representation } ``` -------------------------------- ### Transaction Support in StorageManager Source: https://github.com/facebook/akd/blob/main/_autodocs/04-storage-layer.md Demonstrates how to use the StorageManager for ACID transactions. Begin a transaction, queue operations, and then commit or rollback. ```rust storage.begin_transaction(); // Queue operations (via Directory::publish internally) // ... let num_records = storage.commit_transaction().await?; storage.rollback_transaction()?; ``` -------------------------------- ### Get Current Epoch Hash Source: https://github.com/facebook/akd/blob/main/_autodocs/01-directory-api.md Use get_epoch_hash to retrieve the current epoch and root hash. This is useful for clients to determine when new commitments are available. ```rust let EpochHash(epoch, hash) = dir.get_epoch_hash().await?; println!("Current: epoch={}, hash={}", epoch, hex::encode(hash)); ``` -------------------------------- ### Create AzksElement Instance Source: https://github.com/facebook/akd/blob/main/_autodocs/03-types-and-data-structures.md Shows how to construct an AzksElement using provided NodeLabel and AzksValue. ```rust use akd::{AzksElement, NodeLabel, AzksValue}; let element = AzksElement { label: node_label, value: azks_value, }; ``` -------------------------------- ### Configuration Parameters Source: https://github.com/facebook/akd/blob/main/_autodocs/EXPORTED-SYMBOLS.md Details on configuration structures used for AKD, including parallelism settings for AKSZ and generic parameters for StorageManager and Directory. ```APIDOC ## Configuration Parameters ### AzksParallelismConfig ```rust pub struct AzksParallelismConfig { pub insertion: AzksParallelismOption, pub preload: AzksParallelismOption, } ``` ### StorageManager Generic Parameters ```rust pub struct StorageManager { /* ... */ } ``` ### Directory Generic Parameters ```rust pub struct Directory { where TC: Configuration, S: Database + 'static, V: VRFKeyStorage, } ``` ``` -------------------------------- ### Standard AKD Build (Recommended) Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md This TOML configuration represents the recommended standard build for AKD, which uses the default features. It includes the latest experimental protocol, performance optimizations, and audit proof support. ```toml akd = { version = "0.12.0" } # Uses default features ``` -------------------------------- ### Initialize Tracing for Monitoring Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Shows how to initialize the `tracing` subscriber to enable automatic tracing of AKD operations when the `tracing` feature is enabled. This helps in monitoring and debugging by providing visibility into the library's internal workings. ```rust #[cfg(feature = "tracing")] #[tokio::main] async fn main() -> Result<(), Box> { use tracing_subscriber; // Initialize tracing tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .init(); // Operations are now automatically traced let db = AsyncInMemoryDatabase::new(); let storage = StorageManager::new_no_cache(db); let vrf = HardCodedAkdVRF {}; type Config = WhatsAppV1Configuration; let dir = Directory::::new( storage, vrf, AzksParallelismConfig::default(), ).await?; let EpochHash(epoch, _) = dir.publish(vec![ (AkdLabel::from("alice"), AkdValue::from("key")), ]).await?; println!("Published to epoch {}", epoch); // Tracing spans are automatically emitted Ok(()) } ``` -------------------------------- ### Client-Side Verification with Error Handling Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Demonstrates how to perform client-side verification using `client::lookup_verify` and handle potential `VerificationError` variants. It suggests actions for common failures like proof mismatches or invalid VRF signatures. ```rust use akd::client; match client::lookup_verify::( public_key.as_bytes(), root_hash, epoch, label, proof, ) { Ok(result) => { println!("Verified: version={}, value={:?}", result.version, result.value); }, Err(akd_core::verify::VerificationError::ProofVerificationFailure(msg)) => { eprintln!("Proof invalid: {}", msg); // Possible MITM attack or server malfunction // Obtain root hash from trusted source }, Err(akd_core::verify::VerificationError::VrfProofVerificationFailure(msg)) => { eprintln!("VRF proof invalid: {}", msg); // Public key may be outdated // Fetch fresh public key from server }, Err(e) => eprintln!("Verification error: {}", e), } ``` -------------------------------- ### Preloading Optimization for Tree Traversal Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Shows how to optimize lookup proof generation by preloading necessary nodes using greedy or batch methods, reducing individual storage queries. ```rust // Greedy preload: azks.greedy_preload_lookup_nodes(storage, lookup_info).await?; // Batch preload: azks.preload_lookup_nodes(storage, &lookup_infos, None).await?; ``` -------------------------------- ### Error Handling with Result and Pattern Matching Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Handle AKD operations that return Result. This example demonstrates pattern matching on specific error variants, such as DirectoryError::Publish, and a general error case. ```rust match dir.publish(entries).await { Ok(epoch_hash) => { /* ... */ }, Err(AkdError::Directory(DirectoryError::Publish(msg))) => { eprintln!("Invalid publish: {}", msg); }, Err(e) => eprintln!("Error: {}", e), } ``` -------------------------------- ### Enable Greedy Lookup Preload Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md Enable the greedy_lookup_preload feature to use a greedy algorithm for preloading lookup proof nodes, minimizing storage I/O. ```toml [dependencies] akd = { version = "0.12.0", features = ["greedy_lookup_preload"] } ``` -------------------------------- ### Managing Transactions for Active Transaction Errors Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Ensures proper transaction management to avoid 'Transaction already active' errors. This snippet rolls back any pending transaction before starting a new one and then commits it. ```rust storage.rollback_transaction().ok(); // Clear any pending transaction storage.begin_transaction(); // ... operations ... storage.commit_transaction().await?; ``` -------------------------------- ### Handling NotFound Errors Source: https://github.com/facebook/akd/blob/main/_autodocs/06-errors-and-diagnostics.md Demonstrates the correct sequence for publishing and then querying a label to avoid 'NotFound' errors. Querying before publication can lead to failures. ```rust // Wrong: querying before publication let (proof, _) = dir.lookup(AkdLabel::from("newuser")).await?; // Correct: publish first, then query dir.publish(vec![(AkdLabel::from("newuser"), value)]).await?; let (proof, _) = dir.lookup(AkdLabel::from("newuser")).await?; ``` -------------------------------- ### Add AKD to Cargo.toml Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Add the AKD library and Tokio runtime to your project's Cargo.toml file to begin using AKD. ```toml [dependencies] akd = "0.12.0" tokio = { version = "1", features = ["full"] } ``` -------------------------------- ### VRFPublicKey Structure Source: https://github.com/facebook/akd/blob/main/_autodocs/05-vrf-cryptography.md The VRFPublicKey structure is a wrapper for VRF public keys, designed for safe distribution to clients. It provides methods to get the raw public key bytes and to reconstruct a public key from bytes. ```APIDOC ## VRFPublicKey ### Description Wrapper for VRF public key suitable for distribution to clients. ### Methods - **`as_bytes()`** - **Description**: Get raw public key bytes. - **Returns**: `&[u8]` - **`from_bytes(bytes: &[u8])`** - **Description**: Reconstructs a `VRFPublicKey` from raw bytes. - **Parameters**: - `bytes` (bytes): A slice of bytes representing the public key. - **Returns**: `Result` ``` -------------------------------- ### Get VRF Public Key Source: https://github.com/facebook/akd/blob/main/_autodocs/01-directory-api.md Use get_public_key to retrieve the VRF public key, which clients use to verify VRF proofs in lookup and history proofs. Distribute the key's bytes to clients for verification. ```rust let public_key = dir.get_public_key().await?; // Distribute public_key.as_bytes() to clients ``` -------------------------------- ### Run AKD Benchmarks Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Execute AKD benchmarks using cargo bench, specifically enabling the 'bench' feature. ```bash cargo bench --features bench ``` -------------------------------- ### Serialize and Deserialize Proofs with Serde Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Demonstrates how to serialize and deserialize AKD LookupProofs to and from JSON strings using the `serde_serialization` feature. Ensure the `serde_serialization` feature is enabled for your AKD dependency. ```rust #[cfg(feature = "serde_serialization")] async fn serialize_proof( proof: &LookupProof, ) -> Result> { use serde_json; let json = serde_json::to_string_pretty(&proof)?; Ok(json) } #[cfg(feature = "serde_serialization")] async fn deserialize_proof( json: &str, ) -> Result> { use serde_json; let proof = serde_json::from_str(json)?; Ok(proof) } ``` -------------------------------- ### Server API Overview Source: https://github.com/facebook/akd/blob/main/_autodocs/README.md Overview of the server-side API for managing the auditable key directory. ```APIDOC ## Server API ### Description Provides the core functionality for managing the auditable key directory on the server side. ### Methods - `Directory::new()`: Initialize the directory service. - `publish(entries)`: Add or update entries in the directory. - `lookup(key)`: Generate a lookup proof for a given key. - `batch_lookup(keys)`: Perform efficient batch lookups for multiple keys. - `key_history(key)`: Generate a proof of a key's history. - `audit()`: Generate an append-only audit proof of the directory's state. - `get_public_key()`: Retrieve the public VRF key. - `get_epoch_hash()`: Get the current state hash of the directory. ``` -------------------------------- ### Create AkdLabel from String Source: https://github.com/facebook/akd/blob/main/_autodocs/03-types-and-data-structures.md Demonstrates converting string slices and owned strings into AkdLabel instances. Accessing the inner byte vector is also shown. ```rust use akd::AkdLabel; let label1 = AkdLabel::from("alice"); let label2 = AkdLabel::from("bob".to_string()); let label3 = AkdLabel::from(vec![1, 2, 3]); // Access inner bytes let bytes: &[u8] = &label1.0; ``` -------------------------------- ### Node Hash with Epoch Versioning Source: https://github.com/facebook/akd/blob/main/_autodocs/07-tree-structures.md Demonstrates how a node's hash is versioned by epoch using a HashMap, allowing for historical root hash computation and append-only proofs. ```rust node.hash: HashMap // Example: // epoch 1 → 0xabcd... // epoch 2 → 0xef01... // epoch 3 → 0x2345... ``` -------------------------------- ### Execute local tests Source: https://github.com/facebook/akd/blob/main/TESTING.md Standard commands for running tests within the repository. ```bash cargo test ``` ```bash cargo test --package akd ``` ```bash cd akd cargo test ``` -------------------------------- ### Minimal AKD Build for Testing Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md This TOML configuration creates a minimal AKD build for testing purposes by disabling default features and enabling only the `experimental` feature. This results in the smallest binary size. ```toml akd = { version = "0.12.0", default-features = false, features = ["experimental"] } ``` -------------------------------- ### Enable Public Auditing with Protobuf Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md Enable the public_auditing feature for publishing and serializing audit proofs using protobuf format. Requires the protobuf crate. ```toml [dependencies] akd = { version = "0.12.0", features = ["public_auditing"] } ``` -------------------------------- ### Publish a Single Entry Source: https://github.com/facebook/akd/blob/main/_autodocs/09-examples-and-patterns.md Shows how to publish a single label-value pair to the AKD directory. The result includes the epoch and the root hash of the new state. ```rust use akd::{AkdLabel, AkdValue}; async fn publish_single( dir: &Directory, ) -> Result<(), Box> { let entry = ( AkdLabel::from("alice"), AkdValue::from("alice_public_key_bytes"), ); let EpochHash(epoch, root_hash) = dir.publish(vec![entry]).await?; println!("Published to epoch {} with hash {}", epoch, hex::encode(root_hash)); Ok(()) } ``` -------------------------------- ### Membership Proof Verification Logic Source: https://github.com/facebook/akd/blob/main/_autodocs/10-protocol-specifications.md Outlines the step-by-step process for verifying a membership proof by iteratively computing hashes up to the root. ```rust computed_hash = hash_val for SiblingProof(sibling_label, sibling_hash, direction) in sibling_proofs: if direction == Left: computed_hash = Hash(Hash(sibling_hash || sibling_label), Hash(computed_hash || current_label)) if direction == Right: computed_hash = Hash(Hash(computed_hash || current_label), Hash(sibling_hash || sibling_label)) Update current_label to parent label Final computed_hash should match expected root_hash ``` -------------------------------- ### AKD Benchmark Build Configuration Source: https://github.com/facebook/akd/blob/main/_autodocs/08-configuration-features.md This TOML configuration is designed for running benchmarks with AKD. It includes features like `bench`, `experimental`, `public_tests`, and `slow_internal_db` to enable parallel VRF, multi-threaded Tokio runtime, and performance testing utilities. ```toml [dev-dependencies] akd = { version = "0.12.0", features = [ "bench", "experimental", "public_tests", "slow_internal_db", ] } ```