Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions akd/src/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ use crate::VersionFreshness;
use akd_core::configuration::Configuration;
use akd_core::utils::get_marker_versions;
use akd_core::verify::history::HistoryParams;
use akd_core::VerifiableKeyDirectory;
use async_trait::async_trait;
use std::collections::{HashMap, HashSet};
use std::marker::PhantomData;
use std::sync::Arc;
Expand Down Expand Up @@ -847,6 +849,65 @@ where
}
}

#[async_trait]
impl<TC, S, V> VerifiableKeyDirectory for Directory<TC, S, V>
where
TC: Configuration,
S: Database + 'static,
V: VRFKeyStorage,
{
type LookupProof = LookupProof;
type HistoryProof = HistoryProof;
type AuditProof = AppendOnlyProof;
type PublicKey = VRFPublicKey;
type Error = AkdError;

async fn publish(
&self,
updates: Vec<(AkdLabel, AkdValue)>,
) -> Result<EpochHash, AkdError> {
Directory::publish(self, updates).await
}

async fn lookup(
&self,
label: AkdLabel,
) -> Result<(LookupProof, EpochHash), AkdError> {
Directory::lookup(self, label).await
}

async fn batch_lookup(
&self,
labels: &[AkdLabel],
) -> Result<(Vec<LookupProof>, EpochHash), AkdError> {
Directory::batch_lookup(self, labels).await
}

async fn key_history(
&self,
label: &AkdLabel,
params: HistoryParams,
) -> Result<(HistoryProof, EpochHash), AkdError> {
Directory::key_history(self, label, params).await
}

async fn audit(
&self,
start: u64,
end: u64,
) -> Result<AppendOnlyProof, AkdError> {
Directory::audit(self, start, end).await
}

async fn get_public_key(&self) -> Result<VRFPublicKey, AkdError> {
Directory::get_public_key(self).await
}

async fn get_epoch_hash(&self) -> Result<EpochHash, AkdError> {
Directory::get_epoch_hash(self).await
}
}

/// A thin newtype which offers read-only interactivity with a [Directory].
#[derive(Clone)]
pub struct ReadOnlyDirectory<TC, S, V>(Directory<TC, S, V>)
Expand Down
16 changes: 0 additions & 16 deletions akd/src/helper_structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,8 @@
//! Helper structs that are used for various data structures,
//! to make it easier to pass arguments around.

use crate::Digest;
use crate::{storage::types::ValueState, NodeLabel};

/// Root hash of the tree and its associated epoch
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct EpochHash(pub u64, pub Digest);

impl EpochHash {
/// Get the contained epoch
pub fn epoch(&self) -> u64 {
self.0
}
/// Get the contained hash
pub fn hash(&self) -> Digest {
self.1
}
}

#[derive(Clone, Debug)]
/// Info needed for a lookup of a user for an epoch
pub struct LookupInfo {
Expand Down
3 changes: 1 addition & 2 deletions akd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ pub mod local_auditing;

pub use akd_core::{
configuration, configuration::*, ecvrf, hash, hash::Digest, proto, types::*, verify,
verify::history::HistoryParams, ARITY,
verify::history::HistoryParams, VerifiableKeyDirectory, ARITY,
};

#[macro_use]
Expand All @@ -568,7 +568,6 @@ mod utils;
pub use append_only_zks::{Azks, AzksParallelismConfig, AzksParallelismOption};
pub use client::HistoryVerificationParams;
pub use directory::Directory;
pub use helper_structs::EpochHash;

// ========== Constants and type aliases ========== //
#[cfg(any(test, feature = "public_tests"))]
Expand Down
76 changes: 76 additions & 0 deletions akd_core/src/directory_trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
//
// This source code is dual-licensed under either the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree or the Apache
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree. You may select, at your option, one of the above-listed licenses.

//! Abstract trait for a verifiable key directory.
//!
//! Both AKD (Merkle-tree-based) and other implementations (e.g. polynomial-commitment-based)
//! can implement this trait, enabling consumers to swap backends.

use async_trait::async_trait;

use crate::types::{AkdLabel, AkdValue, EpochHash};
use crate::verify::history::HistoryParams;

/// Abstract Verifiable Key Directory interface.
///
/// This trait defines the core operations that any verifiable key directory
/// must support: publishing updates, looking up entries, querying key history,
/// and generating audit proofs. Proof types and errors are backend-specific
/// associated types.
#[cfg_attr(docsrs, doc(cfg(not(feature = "nostd"))))]
#[async_trait]
pub trait VerifiableKeyDirectory: Send + Sync {
/// The proof type returned by a single-key lookup.
type LookupProof: Send + Sync;
/// The proof type returned by a key history query.
type HistoryProof: Send + Sync;
/// The proof type returned by an audit between two epochs.
type AuditProof: Send + Sync;
/// The public key type for this directory.
type PublicKey: Send + Sync;
/// The error type for this directory.
type Error: std::error::Error + Send + Sync;

/// Publish a batch of label-value updates to the directory, returning the
/// new epoch and root hash.
async fn publish(
&self,
updates: Vec<(AkdLabel, AkdValue)>,
) -> Result<EpochHash, Self::Error>;

/// Generate a lookup proof for a single label at the latest epoch.
async fn lookup(
&self,
label: AkdLabel,
) -> Result<(Self::LookupProof, EpochHash), Self::Error>;

/// Generate lookup proofs for multiple labels at the latest epoch.
async fn batch_lookup(
&self,
labels: &[AkdLabel],
) -> Result<(Vec<Self::LookupProof>, EpochHash), Self::Error>;

/// Generate a key history proof for a label.
async fn key_history(
&self,
label: &AkdLabel,
params: HistoryParams,
) -> Result<(Self::HistoryProof, EpochHash), Self::Error>;

/// Generate an audit proof between two epochs.
async fn audit(
&self,
start: u64,
end: u64,
) -> Result<Self::AuditProof, Self::Error>;

/// Retrieve the public key for this directory.
async fn get_public_key(&self) -> Result<Self::PublicKey, Self::Error>;

/// Retrieve the current epoch and root hash.
async fn get_epoch_hash(&self) -> Result<EpochHash, Self::Error>;
}
5 changes: 5 additions & 0 deletions akd_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ extern crate alloc;
#[cfg(all(feature = "protobuf", not(feature = "nostd")))]
pub mod proto;

#[cfg(not(feature = "nostd"))]
pub mod directory_trait;
#[cfg(not(feature = "nostd"))]
pub use directory_trait::VerifiableKeyDirectory;

pub mod ecvrf;
pub mod hash;
pub mod utils;
Expand Down
15 changes: 15 additions & 0 deletions akd_core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,21 @@ impl AkdValue {
}
}

/// Root hash of the tree and its associated epoch
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct EpochHash(pub u64, pub Digest);

impl EpochHash {
/// Get the contained epoch
pub fn epoch(&self) -> u64 {
self.0
}
/// Get the contained hash
pub fn hash(&self) -> Digest {
self.1
}
}

/// The value to be hashed every time an empty node's hash is to be considered
pub const EMPTY_VALUE: [u8; 1] = [0u8];

Expand Down
Loading